ip_fw_nat.c (266399) | ip_fw_nat.c (272840) |
---|---|
1/*- 2 * Copyright (c) 2008 Paolo Pisati 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 11 unchanged lines hidden (view full) --- 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2008 Paolo Pisati 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 11 unchanged lines hidden (view full) --- 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h> |
28__FBSDID("$FreeBSD: head/sys/netpfil/ipfw/ip_fw_nat.c 266399 2014-05-18 14:25:19Z ae $"); | 28__FBSDID("$FreeBSD: head/sys/netpfil/ipfw/ip_fw_nat.c 272840 2014-10-09 19:32:35Z melifaro $"); |
29 30#include <sys/param.h> 31#include <sys/systm.h> 32#include <sys/eventhandler.h> 33#include <sys/malloc.h> 34#include <sys/mbuf.h> 35#include <sys/kernel.h> 36#include <sys/lock.h> 37#include <sys/module.h> 38#include <sys/rwlock.h> | 29 30#include <sys/param.h> 31#include <sys/systm.h> 32#include <sys/eventhandler.h> 33#include <sys/malloc.h> 34#include <sys/mbuf.h> 35#include <sys/kernel.h> 36#include <sys/lock.h> 37#include <sys/module.h> 38#include <sys/rwlock.h> |
39#include <sys/rmlock.h> |
|
39 | 40 |
40#define IPFW_INTERNAL /* Access to protected data structures in ip_fw.h. */ 41 | |
42#include <netinet/libalias/alias.h> 43#include <netinet/libalias/alias_local.h> 44 45#include <net/if.h> 46#include <net/if_var.h> 47#include <netinet/in.h> 48#include <netinet/ip.h> 49#include <netinet/ip_var.h> 50#include <netinet/ip_fw.h> 51#include <netinet/tcp.h> 52#include <netinet/udp.h> 53 54#include <netpfil/ipfw/ip_fw_private.h> 55 56#include <machine/in_cksum.h> /* XXX for in_cksum */ 57 | 41#include <netinet/libalias/alias.h> 42#include <netinet/libalias/alias_local.h> 43 44#include <net/if.h> 45#include <net/if_var.h> 46#include <netinet/in.h> 47#include <netinet/ip.h> 48#include <netinet/ip_var.h> 49#include <netinet/ip_fw.h> 50#include <netinet/tcp.h> 51#include <netinet/udp.h> 52 53#include <netpfil/ipfw/ip_fw_private.h> 54 55#include <machine/in_cksum.h> /* XXX for in_cksum */ 56 |
57struct cfg_spool { 58 LIST_ENTRY(cfg_spool) _next; /* chain of spool instances */ 59 struct in_addr addr; 60 uint16_t port; 61}; 62 63/* Nat redirect configuration. */ 64struct cfg_redir { 65 LIST_ENTRY(cfg_redir) _next; /* chain of redir instances */ 66 uint16_t mode; /* type of redirect mode */ 67 uint16_t proto; /* protocol: tcp/udp */ 68 struct in_addr laddr; /* local ip address */ 69 struct in_addr paddr; /* public ip address */ 70 struct in_addr raddr; /* remote ip address */ 71 uint16_t lport; /* local port */ 72 uint16_t pport; /* public port */ 73 uint16_t rport; /* remote port */ 74 uint16_t pport_cnt; /* number of public ports */ 75 uint16_t rport_cnt; /* number of remote ports */ 76 struct alias_link **alink; 77 u_int16_t spool_cnt; /* num of entry in spool chain */ 78 /* chain of spool instances */ 79 LIST_HEAD(spool_chain, cfg_spool) spool_chain; 80}; 81 82/* Nat configuration data struct. */ 83struct cfg_nat { 84 /* chain of nat instances */ 85 LIST_ENTRY(cfg_nat) _next; 86 int id; /* nat id */ 87 struct in_addr ip; /* nat ip address */ 88 struct libalias *lib; /* libalias instance */ 89 int mode; /* aliasing mode */ 90 int redir_cnt; /* number of entry in spool chain */ 91 /* chain of redir instances */ 92 LIST_HEAD(redir_chain, cfg_redir) redir_chain; 93 char if_name[IF_NAMESIZE]; /* interface name */ 94}; 95 |
|
58static eventhandler_tag ifaddr_event_tag; 59 60static void 61ifaddr_change(void *arg __unused, struct ifnet *ifp) 62{ 63 struct cfg_nat *ptr; 64 struct ifaddr *ifa; 65 struct ip_fw_chain *chain; --- 46 unchanged lines hidden (view full) --- 112{ 113 struct cfg_redir *r, *tmp_r; 114 struct cfg_spool *s, *tmp_s; 115 int i, num; 116 117 LIST_FOREACH_SAFE(r, head, _next, tmp_r) { 118 num = 1; /* Number of alias_link to delete. */ 119 switch (r->mode) { | 96static eventhandler_tag ifaddr_event_tag; 97 98static void 99ifaddr_change(void *arg __unused, struct ifnet *ifp) 100{ 101 struct cfg_nat *ptr; 102 struct ifaddr *ifa; 103 struct ip_fw_chain *chain; --- 46 unchanged lines hidden (view full) --- 150{ 151 struct cfg_redir *r, *tmp_r; 152 struct cfg_spool *s, *tmp_s; 153 int i, num; 154 155 LIST_FOREACH_SAFE(r, head, _next, tmp_r) { 156 num = 1; /* Number of alias_link to delete. */ 157 switch (r->mode) { |
120 case REDIR_PORT: | 158 case NAT44_REDIR_PORT: |
121 num = r->pport_cnt; 122 /* FALLTHROUGH */ | 159 num = r->pport_cnt; 160 /* FALLTHROUGH */ |
123 case REDIR_ADDR: 124 case REDIR_PROTO: | 161 case NAT44_REDIR_ADDR: 162 case NAT44_REDIR_PROTO: |
125 /* Delete all libalias redirect entry. */ 126 for (i = 0; i < num; i++) 127 LibAliasRedirectDelete(n->lib, r->alink[i]); 128 /* Del spool cfg if any. */ 129 LIST_FOREACH_SAFE(s, &r->spool_chain, _next, tmp_s) { 130 LIST_REMOVE(s, _next); 131 free(s, M_IPFW); 132 } --- 4 unchanged lines hidden (view full) --- 137 default: 138 printf("unknown redirect mode: %u\n", r->mode); 139 /* XXX - panic?!?!? */ 140 break; 141 } 142 } 143} 144 | 163 /* Delete all libalias redirect entry. */ 164 for (i = 0; i < num; i++) 165 LibAliasRedirectDelete(n->lib, r->alink[i]); 166 /* Del spool cfg if any. */ 167 LIST_FOREACH_SAFE(s, &r->spool_chain, _next, tmp_s) { 168 LIST_REMOVE(s, _next); 169 free(s, M_IPFW); 170 } --- 4 unchanged lines hidden (view full) --- 175 default: 176 printf("unknown redirect mode: %u\n", r->mode); 177 /* XXX - panic?!?!? */ 178 break; 179 } 180 } 181} 182 |
145static void | 183static int |
146add_redir_spool_cfg(char *buf, struct cfg_nat *ptr) 147{ | 184add_redir_spool_cfg(char *buf, struct cfg_nat *ptr) 185{ |
148 struct cfg_redir *r, *ser_r; 149 struct cfg_spool *s, *ser_s; | 186 struct cfg_redir *r; 187 struct cfg_spool *s; 188 struct nat44_cfg_redir *ser_r; 189 struct nat44_cfg_spool *ser_s; 190 |
150 int cnt, off, i; 151 152 for (cnt = 0, off = 0; cnt < ptr->redir_cnt; cnt++) { | 191 int cnt, off, i; 192 193 for (cnt = 0, off = 0; cnt < ptr->redir_cnt; cnt++) { |
153 ser_r = (struct cfg_redir *)&buf[off]; 154 r = malloc(SOF_REDIR, M_IPFW, M_WAITOK | M_ZERO); 155 memcpy(r, ser_r, SOF_REDIR); | 194 ser_r = (struct nat44_cfg_redir *)&buf[off]; 195 r = malloc(sizeof(*r), M_IPFW, M_WAITOK | M_ZERO); 196 r->mode = ser_r->mode; 197 r->laddr = ser_r->laddr; 198 r->paddr = ser_r->paddr; 199 r->raddr = ser_r->raddr; 200 r->lport = ser_r->lport; 201 r->pport = ser_r->pport; 202 r->rport = ser_r->rport; 203 r->pport_cnt = ser_r->pport_cnt; 204 r->rport_cnt = ser_r->rport_cnt; 205 r->proto = ser_r->proto; 206 r->spool_cnt = ser_r->spool_cnt; 207 //memcpy(r, ser_r, SOF_REDIR); |
156 LIST_INIT(&r->spool_chain); | 208 LIST_INIT(&r->spool_chain); |
157 off += SOF_REDIR; | 209 off += sizeof(struct nat44_cfg_redir); |
158 r->alink = malloc(sizeof(struct alias_link *) * r->pport_cnt, 159 M_IPFW, M_WAITOK | M_ZERO); 160 switch (r->mode) { | 210 r->alink = malloc(sizeof(struct alias_link *) * r->pport_cnt, 211 M_IPFW, M_WAITOK | M_ZERO); 212 switch (r->mode) { |
161 case REDIR_ADDR: | 213 case NAT44_REDIR_ADDR: |
162 r->alink[0] = LibAliasRedirectAddr(ptr->lib, r->laddr, 163 r->paddr); 164 break; | 214 r->alink[0] = LibAliasRedirectAddr(ptr->lib, r->laddr, 215 r->paddr); 216 break; |
165 case REDIR_PORT: | 217 case NAT44_REDIR_PORT: |
166 for (i = 0 ; i < r->pport_cnt; i++) { 167 /* If remotePort is all ports, set it to 0. */ 168 u_short remotePortCopy = r->rport + i; 169 if (r->rport_cnt == 1 && r->rport == 0) 170 remotePortCopy = 0; 171 r->alink[i] = LibAliasRedirectPort(ptr->lib, 172 r->laddr, htons(r->lport + i), r->raddr, 173 htons(remotePortCopy), r->paddr, 174 htons(r->pport + i), r->proto); 175 if (r->alink[i] == NULL) { 176 r->alink[0] = NULL; 177 break; 178 } 179 } 180 break; | 218 for (i = 0 ; i < r->pport_cnt; i++) { 219 /* If remotePort is all ports, set it to 0. */ 220 u_short remotePortCopy = r->rport + i; 221 if (r->rport_cnt == 1 && r->rport == 0) 222 remotePortCopy = 0; 223 r->alink[i] = LibAliasRedirectPort(ptr->lib, 224 r->laddr, htons(r->lport + i), r->raddr, 225 htons(remotePortCopy), r->paddr, 226 htons(r->pport + i), r->proto); 227 if (r->alink[i] == NULL) { 228 r->alink[0] = NULL; 229 break; 230 } 231 } 232 break; |
181 case REDIR_PROTO: | 233 case NAT44_REDIR_PROTO: |
182 r->alink[0] = LibAliasRedirectProto(ptr->lib ,r->laddr, 183 r->raddr, r->paddr, r->proto); 184 break; 185 default: 186 printf("unknown redirect mode: %u\n", r->mode); 187 break; 188 } | 234 r->alink[0] = LibAliasRedirectProto(ptr->lib ,r->laddr, 235 r->raddr, r->paddr, r->proto); 236 break; 237 default: 238 printf("unknown redirect mode: %u\n", r->mode); 239 break; 240 } |
189 /* XXX perhaps return an error instead of panic ? */ 190 if (r->alink[0] == NULL) 191 panic("LibAliasRedirect* returned NULL"); | 241 if (r->alink[0] == NULL) { 242 printf("LibAliasRedirect* returned NULL\n"); 243 return (EINVAL); 244 } |
192 /* LSNAT handling. */ 193 for (i = 0; i < r->spool_cnt; i++) { | 245 /* LSNAT handling. */ 246 for (i = 0; i < r->spool_cnt; i++) { |
194 ser_s = (struct cfg_spool *)&buf[off]; 195 s = malloc(SOF_REDIR, M_IPFW, M_WAITOK | M_ZERO); 196 memcpy(s, ser_s, SOF_SPOOL); | 247 ser_s = (struct nat44_cfg_spool *)&buf[off]; 248 s = malloc(sizeof(*s), M_IPFW, M_WAITOK | M_ZERO); 249 s->addr = ser_s->addr; 250 s->port = ser_s->port; |
197 LibAliasAddServer(ptr->lib, r->alink[0], 198 s->addr, htons(s->port)); | 251 LibAliasAddServer(ptr->lib, r->alink[0], 252 s->addr, htons(s->port)); |
199 off += SOF_SPOOL; | 253 off += sizeof(struct nat44_cfg_spool); |
200 /* Hook spool entry. */ 201 LIST_INSERT_HEAD(&r->spool_chain, s, _next); 202 } 203 /* And finally hook this redir entry. */ 204 LIST_INSERT_HEAD(&ptr->redir_chain, r, _next); 205 } | 254 /* Hook spool entry. */ 255 LIST_INSERT_HEAD(&r->spool_chain, s, _next); 256 } 257 /* And finally hook this redir entry. */ 258 LIST_INSERT_HEAD(&ptr->redir_chain, r, _next); 259 } |
260 261 return (0); |
|
206} 207 208/* 209 * ipfw_nat - perform mbuf header translation. 210 * 211 * Note V_layer3_chain has to be locked while calling ipfw_nat() in 212 * 'global' operation mode (t == NULL). 213 * --- 173 unchanged lines hidden (view full) --- 387 388 LIST_FOREACH(res, l, _next) { 389 if (res->id == nat_id) 390 break; 391 } 392 return res; 393} 394 | 262} 263 264/* 265 * ipfw_nat - perform mbuf header translation. 266 * 267 * Note V_layer3_chain has to be locked while calling ipfw_nat() in 268 * 'global' operation mode (t == NULL). 269 * --- 173 unchanged lines hidden (view full) --- 443 444 LIST_FOREACH(res, l, _next) { 445 if (res->id == nat_id) 446 break; 447 } 448 return res; 449} 450 |
395static int 396ipfw_nat_cfg(struct sockopt *sopt) | 451static struct cfg_nat * 452lookup_nat_name(struct nat_list *l, char *name) |
397{ | 453{ |
398 struct cfg_nat *cfg, *ptr; 399 char *buf; 400 struct ip_fw_chain *chain = &V_layer3_chain; 401 size_t len; 402 int gencnt, error = 0; | 454 struct cfg_nat *res; 455 int id; 456 char *errptr; |
403 | 457 |
404 len = sopt->sopt_valsize; 405 buf = malloc(len, M_TEMP, M_WAITOK | M_ZERO); 406 if ((error = sooptcopyin(sopt, buf, len, sizeof(struct cfg_nat))) != 0) 407 goto out; | 458 id = strtol(name, &errptr, 10); 459 if (id == 0 || *errptr != '\0') 460 return (NULL); |
408 | 461 |
409 cfg = (struct cfg_nat *)buf; 410 if (cfg->id < 0) { 411 error = EINVAL; 412 goto out; | 462 LIST_FOREACH(res, l, _next) { 463 if (res->id == id) 464 break; |
413 } | 465 } |
466 return (res); 467} |
|
414 | 468 |
469/* IP_FW3 configuration routines */ 470 471static void 472nat44_config(struct ip_fw_chain *chain, struct nat44_cfg_nat *ucfg) 473{ 474 struct cfg_nat *ptr, *tcfg; 475 int gencnt; 476 |
|
415 /* 416 * Find/create nat rule. 417 */ | 477 /* 478 * Find/create nat rule. 479 */ |
418 IPFW_WLOCK(chain); | 480 IPFW_UH_WLOCK(chain); |
419 gencnt = chain->gencnt; | 481 gencnt = chain->gencnt; |
420 ptr = lookup_nat(&chain->nat, cfg->id); | 482 ptr = lookup_nat_name(&chain->nat, ucfg->name); |
421 if (ptr == NULL) { | 483 if (ptr == NULL) { |
422 IPFW_WUNLOCK(chain); | 484 IPFW_UH_WUNLOCK(chain); |
423 /* New rule: allocate and init new instance. */ 424 ptr = malloc(sizeof(struct cfg_nat), M_IPFW, M_WAITOK | M_ZERO); 425 ptr->lib = LibAliasInit(NULL); 426 LIST_INIT(&ptr->redir_chain); 427 } else { 428 /* Entry already present: temporarily unhook it. */ | 485 /* New rule: allocate and init new instance. */ 486 ptr = malloc(sizeof(struct cfg_nat), M_IPFW, M_WAITOK | M_ZERO); 487 ptr->lib = LibAliasInit(NULL); 488 LIST_INIT(&ptr->redir_chain); 489 } else { 490 /* Entry already present: temporarily unhook it. */ |
491 IPFW_WLOCK(chain); |
|
429 LIST_REMOVE(ptr, _next); | 492 LIST_REMOVE(ptr, _next); |
430 flush_nat_ptrs(chain, cfg->id); | 493 flush_nat_ptrs(chain, ptr->id); |
431 IPFW_WUNLOCK(chain); | 494 IPFW_WUNLOCK(chain); |
495 IPFW_UH_WUNLOCK(chain); |
|
432 } 433 434 /* | 496 } 497 498 /* |
435 * Basic nat configuration. | 499 * Basic nat (re)configuration. |
436 */ | 500 */ |
437 ptr->id = cfg->id; | 501 ptr->id = strtol(ucfg->name, NULL, 10); |
438 /* 439 * XXX - what if this rule doesn't nat any ip and just 440 * redirect? 441 * do we set aliasaddress to 0.0.0.0? 442 */ | 502 /* 503 * XXX - what if this rule doesn't nat any ip and just 504 * redirect? 505 * do we set aliasaddress to 0.0.0.0? 506 */ |
443 ptr->ip = cfg->ip; 444 ptr->redir_cnt = cfg->redir_cnt; 445 ptr->mode = cfg->mode; 446 LibAliasSetMode(ptr->lib, cfg->mode, ~0); | 507 ptr->ip = ucfg->ip; 508 ptr->redir_cnt = ucfg->redir_cnt; 509 ptr->mode = ucfg->mode; 510 strlcpy(ptr->if_name, ucfg->if_name, sizeof(ptr->if_name)); 511 LibAliasSetMode(ptr->lib, ptr->mode, ~0); |
447 LibAliasSetAddress(ptr->lib, ptr->ip); | 512 LibAliasSetAddress(ptr->lib, ptr->ip); |
448 memcpy(ptr->if_name, cfg->if_name, IF_NAMESIZE); | |
449 450 /* 451 * Redir and LSNAT configuration. 452 */ 453 /* Delete old cfgs. */ 454 del_redir_spool_cfg(ptr, &ptr->redir_chain); 455 /* Add new entries. */ | 513 514 /* 515 * Redir and LSNAT configuration. 516 */ 517 /* Delete old cfgs. */ 518 del_redir_spool_cfg(ptr, &ptr->redir_chain); 519 /* Add new entries. */ |
456 add_redir_spool_cfg(&buf[(sizeof(struct cfg_nat))], ptr); | 520 add_redir_spool_cfg((char *)(ucfg + 1), ptr); 521 IPFW_UH_WLOCK(chain); |
457 | 522 |
458 IPFW_WLOCK(chain); | |
459 /* Extra check to avoid race with another ipfw_nat_cfg() */ | 523 /* Extra check to avoid race with another ipfw_nat_cfg() */ |
460 if (gencnt != chain->gencnt && 461 ((cfg = lookup_nat(&chain->nat, ptr->id)) != NULL)) 462 LIST_REMOVE(cfg, _next); | 524 tcfg = NULL; 525 if (gencnt != chain->gencnt) 526 tcfg = lookup_nat_name(&chain->nat, ucfg->name); 527 IPFW_WLOCK(chain); 528 if (tcfg != NULL) 529 LIST_REMOVE(tcfg, _next); |
463 LIST_INSERT_HEAD(&chain->nat, ptr, _next); | 530 LIST_INSERT_HEAD(&chain->nat, ptr, _next); |
531 IPFW_WUNLOCK(chain); |
|
464 chain->gencnt++; | 532 chain->gencnt++; |
533 534 IPFW_UH_WUNLOCK(chain); 535 536 if (tcfg != NULL) 537 free(tcfg, M_IPFW); 538} 539 540/* 541 * Creates/configure nat44 instance 542 * Data layout (v0)(current): 543 * Request: [ ipfw_obj_header nat44_cfg_nat .. ] 544 * 545 * Returns 0 on success 546 */ 547static int 548nat44_cfg(struct ip_fw_chain *chain, ip_fw3_opheader *op3, 549 struct sockopt_data *sd) 550{ 551 ipfw_obj_header *oh; 552 struct nat44_cfg_nat *ucfg; 553 int id; 554 size_t read; 555 char *errptr; 556 557 /* Check minimum header size */ 558 if (sd->valsize < (sizeof(*oh) + sizeof(*ucfg))) 559 return (EINVAL); 560 561 oh = (ipfw_obj_header *)sd->kbuf; 562 563 /* Basic length checks for TLVs */ 564 if (oh->ntlv.head.length != sizeof(oh->ntlv)) 565 return (EINVAL); 566 567 ucfg = (struct nat44_cfg_nat *)(oh + 1); 568 569 /* Check if name is properly terminated and looks like number */ 570 if (strnlen(ucfg->name, sizeof(ucfg->name)) == sizeof(ucfg->name)) 571 return (EINVAL); 572 id = strtol(ucfg->name, &errptr, 10); 573 if (id == 0 || *errptr != '\0') 574 return (EINVAL); 575 576 read = sizeof(*oh) + sizeof(*ucfg); 577 /* Check number of redirs */ 578 if (sd->valsize < read + ucfg->redir_cnt*sizeof(struct nat44_cfg_redir)) 579 return (EINVAL); 580 581 nat44_config(chain, ucfg); 582 return (0); 583} 584 585/* 586 * Destroys given nat instances. 587 * Data layout (v0)(current): 588 * Request: [ ipfw_obj_header ] 589 * 590 * Returns 0 on success 591 */ 592static int 593nat44_destroy(struct ip_fw_chain *chain, ip_fw3_opheader *op3, 594 struct sockopt_data *sd) 595{ 596 ipfw_obj_header *oh; 597 struct cfg_nat *ptr; 598 ipfw_obj_ntlv *ntlv; 599 600 /* Check minimum header size */ 601 if (sd->valsize < sizeof(*oh)) 602 return (EINVAL); 603 604 oh = (ipfw_obj_header *)sd->kbuf; 605 606 /* Basic length checks for TLVs */ 607 if (oh->ntlv.head.length != sizeof(oh->ntlv)) 608 return (EINVAL); 609 610 ntlv = &oh->ntlv; 611 /* Check if name is properly terminated */ 612 if (strnlen(ntlv->name, sizeof(ntlv->name)) == sizeof(ntlv->name)) 613 return (EINVAL); 614 615 IPFW_UH_WLOCK(chain); 616 ptr = lookup_nat_name(&chain->nat, ntlv->name); 617 if (ptr == NULL) { 618 IPFW_UH_WUNLOCK(chain); 619 return (ESRCH); 620 } 621 IPFW_WLOCK(chain); 622 LIST_REMOVE(ptr, _next); 623 flush_nat_ptrs(chain, ptr->id); |
|
465 IPFW_WUNLOCK(chain); | 624 IPFW_WUNLOCK(chain); |
625 IPFW_UH_WUNLOCK(chain); |
|
466 | 626 |
627 del_redir_spool_cfg(ptr, &ptr->redir_chain); 628 LibAliasUninit(ptr->lib); 629 free(ptr, M_IPFW); 630 631 return (0); 632} 633 634static void 635export_nat_cfg(struct cfg_nat *ptr, struct nat44_cfg_nat *ucfg) 636{ 637 638 snprintf(ucfg->name, sizeof(ucfg->name), "%d", ptr->id); 639 ucfg->ip = ptr->ip; 640 ucfg->redir_cnt = ptr->redir_cnt; 641 ucfg->mode = ptr->mode; 642 strlcpy(ucfg->if_name, ptr->if_name, sizeof(ucfg->if_name)); 643} 644 645/* 646 * Gets config for given nat instance 647 * Data layout (v0)(current): 648 * Request: [ ipfw_obj_header nat44_cfg_nat .. ] 649 * 650 * Returns 0 on success 651 */ 652static int 653nat44_get_cfg(struct ip_fw_chain *chain, ip_fw3_opheader *op3, 654 struct sockopt_data *sd) 655{ 656 ipfw_obj_header *oh; 657 struct nat44_cfg_nat *ucfg; 658 struct cfg_nat *ptr; 659 struct cfg_redir *r; 660 struct cfg_spool *s; 661 struct nat44_cfg_redir *ser_r; 662 struct nat44_cfg_spool *ser_s; 663 size_t sz; 664 665 sz = sizeof(*oh) + sizeof(*ucfg); 666 /* Check minimum header size */ 667 if (sd->valsize < sz) 668 return (EINVAL); 669 670 oh = (struct _ipfw_obj_header *)ipfw_get_sopt_header(sd, sz); 671 672 /* Basic length checks for TLVs */ 673 if (oh->ntlv.head.length != sizeof(oh->ntlv)) 674 return (EINVAL); 675 676 ucfg = (struct nat44_cfg_nat *)(oh + 1); 677 678 /* Check if name is properly terminated */ 679 if (strnlen(ucfg->name, sizeof(ucfg->name)) == sizeof(ucfg->name)) 680 return (EINVAL); 681 682 IPFW_UH_RLOCK(chain); 683 ptr = lookup_nat_name(&chain->nat, ucfg->name); 684 if (ptr == NULL) { 685 IPFW_UH_RUNLOCK(chain); 686 return (ESRCH); 687 } 688 689 export_nat_cfg(ptr, ucfg); 690 691 /* Estimate memory amount */ 692 sz = sizeof(struct nat44_cfg_nat); 693 LIST_FOREACH(r, &ptr->redir_chain, _next) { 694 sz += sizeof(struct nat44_cfg_redir); 695 LIST_FOREACH(s, &r->spool_chain, _next) 696 sz += sizeof(struct nat44_cfg_spool); 697 } 698 699 ucfg->size = sz; 700 if (sd->valsize < sz + sizeof(*oh)) { 701 702 /* 703 * Submitted buffer size is not enough. 704 * WE've already filled in @ucfg structure with 705 * relevant info including size, so we 706 * can return. Buffer will be flushed automatically. 707 */ 708 IPFW_UH_RUNLOCK(chain); 709 return (ENOMEM); 710 } 711 712 /* Size OK, let's copy data */ 713 LIST_FOREACH(r, &ptr->redir_chain, _next) { 714 ser_r = (struct nat44_cfg_redir *)ipfw_get_sopt_space(sd, 715 sizeof(*ser_r)); 716 ser_r->mode = r->mode; 717 ser_r->laddr = r->laddr; 718 ser_r->paddr = r->paddr; 719 ser_r->raddr = r->raddr; 720 ser_r->lport = r->lport; 721 ser_r->pport = r->pport; 722 ser_r->rport = r->rport; 723 ser_r->pport_cnt = r->pport_cnt; 724 ser_r->rport_cnt = r->rport_cnt; 725 ser_r->proto = r->proto; 726 ser_r->spool_cnt = r->spool_cnt; 727 728 LIST_FOREACH(s, &r->spool_chain, _next) { 729 ser_s = (struct nat44_cfg_spool *)ipfw_get_sopt_space( 730 sd, sizeof(*ser_s)); 731 732 ser_s->addr = s->addr; 733 ser_s->port = s->port; 734 } 735 } 736 737 IPFW_UH_RUNLOCK(chain); 738 739 return (0); 740} 741 742/* 743 * Lists all nat44 instances currently available in kernel. 744 * Data layout (v0)(current): 745 * Request: [ ipfw_obj_lheader ] 746 * Reply: [ ipfw_obj_lheader nat44_cfg_nat x N ] 747 * 748 * Returns 0 on success 749 */ 750static int 751nat44_list_nat(struct ip_fw_chain *chain, ip_fw3_opheader *op3, 752 struct sockopt_data *sd) 753{ 754 ipfw_obj_lheader *olh; 755 struct nat44_cfg_nat *ucfg; 756 struct cfg_nat *ptr; 757 int nat_count; 758 759 /* Check minimum header size */ 760 if (sd->valsize < sizeof(ipfw_obj_lheader)) 761 return (EINVAL); 762 763 olh = (ipfw_obj_lheader *)ipfw_get_sopt_header(sd, sizeof(*olh)); 764 IPFW_UH_RLOCK(chain); 765 nat_count = 0; 766 LIST_FOREACH(ptr, &chain->nat, _next) 767 nat_count++; 768 769 olh->count = nat_count; 770 olh->objsize = sizeof(struct nat44_cfg_nat); 771 olh->size = sizeof(*olh) + olh->count * olh->objsize; 772 773 if (sd->valsize < olh->size) { 774 IPFW_UH_RUNLOCK(chain); 775 return (ENOMEM); 776 } 777 778 LIST_FOREACH(ptr, &chain->nat, _next) { 779 ucfg = (struct nat44_cfg_nat *)ipfw_get_sopt_space(sd, 780 sizeof(*ucfg)); 781 export_nat_cfg(ptr, ucfg); 782 } 783 784 IPFW_UH_RUNLOCK(chain); 785 786 return (0); 787} 788 789/* 790 * Gets log for given nat instance 791 * Data layout (v0)(current): 792 * Request: [ ipfw_obj_header nat44_cfg_nat ] 793 * Reply: [ ipfw_obj_header nat44_cfg_nat LOGBUFFER ] 794 * 795 * Returns 0 on success 796 */ 797static int 798nat44_get_log(struct ip_fw_chain *chain, ip_fw3_opheader *op3, 799 struct sockopt_data *sd) 800{ 801 ipfw_obj_header *oh; 802 struct nat44_cfg_nat *ucfg; 803 struct cfg_nat *ptr; 804 void *pbuf; 805 size_t sz; 806 807 sz = sizeof(*oh) + sizeof(*ucfg); 808 /* Check minimum header size */ 809 if (sd->valsize < sz) 810 return (EINVAL); 811 812 oh = (struct _ipfw_obj_header *)ipfw_get_sopt_header(sd, sz); 813 814 /* Basic length checks for TLVs */ 815 if (oh->ntlv.head.length != sizeof(oh->ntlv)) 816 return (EINVAL); 817 818 ucfg = (struct nat44_cfg_nat *)(oh + 1); 819 820 /* Check if name is properly terminated */ 821 if (strnlen(ucfg->name, sizeof(ucfg->name)) == sizeof(ucfg->name)) 822 return (EINVAL); 823 824 IPFW_UH_RLOCK(chain); 825 ptr = lookup_nat_name(&chain->nat, ucfg->name); 826 if (ptr == NULL) { 827 IPFW_UH_RUNLOCK(chain); 828 return (ESRCH); 829 } 830 831 if (ptr->lib->logDesc == NULL) { 832 IPFW_UH_RUNLOCK(chain); 833 return (ENOENT); 834 } 835 836 export_nat_cfg(ptr, ucfg); 837 838 /* Estimate memory amount */ 839 ucfg->size = sizeof(struct nat44_cfg_nat) + LIBALIAS_BUF_SIZE; 840 if (sd->valsize < sz + sizeof(*oh)) { 841 842 /* 843 * Submitted buffer size is not enough. 844 * WE've already filled in @ucfg structure with 845 * relevant info including size, so we 846 * can return. Buffer will be flushed automatically. 847 */ 848 IPFW_UH_RUNLOCK(chain); 849 return (ENOMEM); 850 } 851 852 pbuf = (void *)ipfw_get_sopt_space(sd, LIBALIAS_BUF_SIZE); 853 memcpy(pbuf, ptr->lib->logDesc, LIBALIAS_BUF_SIZE); 854 855 IPFW_UH_RUNLOCK(chain); 856 857 return (0); 858} 859 860static struct ipfw_sopt_handler scodes[] = { 861 { IP_FW_NAT44_XCONFIG, 0, HDIR_SET, nat44_cfg }, 862 { IP_FW_NAT44_DESTROY, 0, HDIR_SET, nat44_destroy }, 863 { IP_FW_NAT44_XGETCONFIG, 0, HDIR_GET, nat44_get_cfg }, 864 { IP_FW_NAT44_LIST_NAT, 0, HDIR_GET, nat44_list_nat }, 865 { IP_FW_NAT44_XGETLOG, 0, HDIR_GET, nat44_get_log }, 866}; 867 868 869/* 870 * Legacy configuration routines 871 */ 872 873struct cfg_spool_legacy { 874 LIST_ENTRY(cfg_spool_legacy) _next; 875 struct in_addr addr; 876 u_short port; 877}; 878 879struct cfg_redir_legacy { 880 LIST_ENTRY(cfg_redir) _next; 881 u_int16_t mode; 882 struct in_addr laddr; 883 struct in_addr paddr; 884 struct in_addr raddr; 885 u_short lport; 886 u_short pport; 887 u_short rport; 888 u_short pport_cnt; 889 u_short rport_cnt; 890 int proto; 891 struct alias_link **alink; 892 u_int16_t spool_cnt; 893 LIST_HEAD(, cfg_spool_legacy) spool_chain; 894}; 895 896struct cfg_nat_legacy { 897 LIST_ENTRY(cfg_nat_legacy) _next; 898 int id; 899 struct in_addr ip; 900 char if_name[IF_NAMESIZE]; 901 int mode; 902 struct libalias *lib; 903 int redir_cnt; 904 LIST_HEAD(, cfg_redir_legacy) redir_chain; 905}; 906 907static int 908ipfw_nat_cfg(struct sockopt *sopt) 909{ 910 struct cfg_nat_legacy *cfg; 911 struct nat44_cfg_nat *ucfg; 912 struct cfg_redir_legacy *rdir; 913 struct nat44_cfg_redir *urdir; 914 char *buf; 915 size_t len, len2; 916 int error, i; 917 918 len = sopt->sopt_valsize; 919 len2 = len + 128; 920 921 /* 922 * Allocate 2x buffer to store converted structures. 923 * new redir_cfg has shrinked, so we're sure that 924 * new buffer size is enough. 925 */ 926 buf = malloc(roundup2(len, 8) + len2, M_TEMP, M_WAITOK | M_ZERO); 927 error = sooptcopyin(sopt, buf, len, sizeof(struct cfg_nat_legacy)); 928 if (error != 0) 929 goto out; 930 931 cfg = (struct cfg_nat_legacy *)buf; 932 if (cfg->id < 0) { 933 error = EINVAL; 934 goto out; 935 } 936 937 ucfg = (struct nat44_cfg_nat *)&buf[roundup2(len, 8)]; 938 snprintf(ucfg->name, sizeof(ucfg->name), "%d", cfg->id); 939 strlcpy(ucfg->if_name, cfg->if_name, sizeof(ucfg->if_name)); 940 ucfg->ip = cfg->ip; 941 ucfg->mode = cfg->mode; 942 ucfg->redir_cnt = cfg->redir_cnt; 943 944 if (len < sizeof(*cfg) + cfg->redir_cnt * sizeof(*rdir)) { 945 error = EINVAL; 946 goto out; 947 } 948 949 urdir = (struct nat44_cfg_redir *)(ucfg + 1); 950 rdir = (struct cfg_redir_legacy *)(cfg + 1); 951 for (i = 0; i < cfg->redir_cnt; i++) { 952 urdir->mode = rdir->mode; 953 urdir->laddr = rdir->laddr; 954 urdir->paddr = rdir->paddr; 955 urdir->raddr = rdir->raddr; 956 urdir->lport = rdir->lport; 957 urdir->pport = rdir->pport; 958 urdir->rport = rdir->rport; 959 urdir->pport_cnt = rdir->pport_cnt; 960 urdir->rport_cnt = rdir->rport_cnt; 961 urdir->proto = rdir->proto; 962 urdir->spool_cnt = rdir->spool_cnt; 963 964 urdir++; 965 rdir++; 966 } 967 968 nat44_config(&V_layer3_chain, ucfg); 969 |
|
467out: 468 free(buf, M_TEMP); 469 return (error); 470} 471 472static int 473ipfw_nat_del(struct sockopt *sopt) 474{ 475 struct cfg_nat *ptr; 476 struct ip_fw_chain *chain = &V_layer3_chain; 477 int i; 478 479 sooptcopyin(sopt, &i, sizeof i, sizeof i); 480 /* XXX validate i */ | 970out: 971 free(buf, M_TEMP); 972 return (error); 973} 974 975static int 976ipfw_nat_del(struct sockopt *sopt) 977{ 978 struct cfg_nat *ptr; 979 struct ip_fw_chain *chain = &V_layer3_chain; 980 int i; 981 982 sooptcopyin(sopt, &i, sizeof i, sizeof i); 983 /* XXX validate i */ |
481 IPFW_WLOCK(chain); | 984 IPFW_UH_WLOCK(chain); |
482 ptr = lookup_nat(&chain->nat, i); 483 if (ptr == NULL) { | 985 ptr = lookup_nat(&chain->nat, i); 986 if (ptr == NULL) { |
484 IPFW_WUNLOCK(chain); | 987 IPFW_UH_WUNLOCK(chain); |
485 return (EINVAL); 486 } | 988 return (EINVAL); 989 } |
990 IPFW_WLOCK(chain); |
|
487 LIST_REMOVE(ptr, _next); 488 flush_nat_ptrs(chain, i); 489 IPFW_WUNLOCK(chain); | 991 LIST_REMOVE(ptr, _next); 992 flush_nat_ptrs(chain, i); 993 IPFW_WUNLOCK(chain); |
994 IPFW_UH_WUNLOCK(chain); |
|
490 del_redir_spool_cfg(ptr, &ptr->redir_chain); 491 LibAliasUninit(ptr->lib); 492 free(ptr, M_IPFW); 493 return (0); 494} 495 496static int 497ipfw_nat_get_cfg(struct sockopt *sopt) 498{ 499 struct ip_fw_chain *chain = &V_layer3_chain; 500 struct cfg_nat *n; | 995 del_redir_spool_cfg(ptr, &ptr->redir_chain); 996 LibAliasUninit(ptr->lib); 997 free(ptr, M_IPFW); 998 return (0); 999} 1000 1001static int 1002ipfw_nat_get_cfg(struct sockopt *sopt) 1003{ 1004 struct ip_fw_chain *chain = &V_layer3_chain; 1005 struct cfg_nat *n; |
1006 struct cfg_nat_legacy *ucfg; |
|
501 struct cfg_redir *r; 502 struct cfg_spool *s; | 1007 struct cfg_redir *r; 1008 struct cfg_spool *s; |
1009 struct cfg_redir_legacy *ser_r; 1010 struct cfg_spool_legacy *ser_s; |
|
503 char *data; 504 int gencnt, nat_cnt, len, error; 505 506 nat_cnt = 0; 507 len = sizeof(nat_cnt); 508 | 1011 char *data; 1012 int gencnt, nat_cnt, len, error; 1013 1014 nat_cnt = 0; 1015 len = sizeof(nat_cnt); 1016 |
509 IPFW_RLOCK(chain); | 1017 IPFW_UH_RLOCK(chain); |
510retry: 511 gencnt = chain->gencnt; 512 /* Estimate memory amount */ 513 LIST_FOREACH(n, &chain->nat, _next) { 514 nat_cnt++; | 1018retry: 1019 gencnt = chain->gencnt; 1020 /* Estimate memory amount */ 1021 LIST_FOREACH(n, &chain->nat, _next) { 1022 nat_cnt++; |
515 len += sizeof(struct cfg_nat); | 1023 len += sizeof(struct cfg_nat_legacy); |
516 LIST_FOREACH(r, &n->redir_chain, _next) { | 1024 LIST_FOREACH(r, &n->redir_chain, _next) { |
517 len += sizeof(struct cfg_redir); | 1025 len += sizeof(struct cfg_redir_legacy); |
518 LIST_FOREACH(s, &r->spool_chain, _next) | 1026 LIST_FOREACH(s, &r->spool_chain, _next) |
519 len += sizeof(struct cfg_spool); | 1027 len += sizeof(struct cfg_spool_legacy); |
520 } 521 } | 1028 } 1029 } |
522 IPFW_RUNLOCK(chain); | 1030 IPFW_UH_RUNLOCK(chain); |
523 524 data = malloc(len, M_TEMP, M_WAITOK | M_ZERO); 525 bcopy(&nat_cnt, data, sizeof(nat_cnt)); 526 527 nat_cnt = 0; 528 len = sizeof(nat_cnt); 529 | 1031 1032 data = malloc(len, M_TEMP, M_WAITOK | M_ZERO); 1033 bcopy(&nat_cnt, data, sizeof(nat_cnt)); 1034 1035 nat_cnt = 0; 1036 len = sizeof(nat_cnt); 1037 |
530 IPFW_RLOCK(chain); | 1038 IPFW_UH_RLOCK(chain); |
531 if (gencnt != chain->gencnt) { 532 free(data, M_TEMP); 533 goto retry; 534 } 535 /* Serialize all the data. */ 536 LIST_FOREACH(n, &chain->nat, _next) { | 1039 if (gencnt != chain->gencnt) { 1040 free(data, M_TEMP); 1041 goto retry; 1042 } 1043 /* Serialize all the data. */ 1044 LIST_FOREACH(n, &chain->nat, _next) { |
537 bcopy(n, &data[len], sizeof(struct cfg_nat)); 538 len += sizeof(struct cfg_nat); | 1045 ucfg = (struct cfg_nat_legacy *)&data[len]; 1046 ucfg->id = n->id; 1047 ucfg->ip = n->ip; 1048 ucfg->redir_cnt = n->redir_cnt; 1049 ucfg->mode = n->mode; 1050 strlcpy(ucfg->if_name, n->if_name, sizeof(ucfg->if_name)); 1051 len += sizeof(struct cfg_nat_legacy); |
539 LIST_FOREACH(r, &n->redir_chain, _next) { | 1052 LIST_FOREACH(r, &n->redir_chain, _next) { |
540 bcopy(r, &data[len], sizeof(struct cfg_redir)); 541 len += sizeof(struct cfg_redir); | 1053 ser_r = (struct cfg_redir_legacy *)&data[len]; 1054 ser_r->mode = r->mode; 1055 ser_r->laddr = r->laddr; 1056 ser_r->paddr = r->paddr; 1057 ser_r->raddr = r->raddr; 1058 ser_r->lport = r->lport; 1059 ser_r->pport = r->pport; 1060 ser_r->rport = r->rport; 1061 ser_r->pport_cnt = r->pport_cnt; 1062 ser_r->rport_cnt = r->rport_cnt; 1063 ser_r->proto = r->proto; 1064 ser_r->spool_cnt = r->spool_cnt; 1065 len += sizeof(struct cfg_redir_legacy); |
542 LIST_FOREACH(s, &r->spool_chain, _next) { | 1066 LIST_FOREACH(s, &r->spool_chain, _next) { |
543 bcopy(s, &data[len], sizeof(struct cfg_spool)); 544 len += sizeof(struct cfg_spool); | 1067 ser_s = (struct cfg_spool_legacy *)&data[len]; 1068 ser_s->addr = s->addr; 1069 ser_s->port = s->port; 1070 len += sizeof(struct cfg_spool_legacy); |
545 } 546 } 547 } | 1071 } 1072 } 1073 } |
548 IPFW_RUNLOCK(chain); | 1074 IPFW_UH_RUNLOCK(chain); |
549 550 error = sooptcopyout(sopt, data, len); 551 free(data, M_TEMP); 552 553 return (error); 554} 555 556static int 557ipfw_nat_get_log(struct sockopt *sopt) 558{ 559 uint8_t *data; 560 struct cfg_nat *ptr; 561 int i, size; 562 struct ip_fw_chain *chain; | 1075 1076 error = sooptcopyout(sopt, data, len); 1077 free(data, M_TEMP); 1078 1079 return (error); 1080} 1081 1082static int 1083ipfw_nat_get_log(struct sockopt *sopt) 1084{ 1085 uint8_t *data; 1086 struct cfg_nat *ptr; 1087 int i, size; 1088 struct ip_fw_chain *chain; |
1089 IPFW_RLOCK_TRACKER; |
|
563 564 chain = &V_layer3_chain; 565 566 IPFW_RLOCK(chain); 567 /* one pass to count, one to copy the data */ 568 i = 0; 569 LIST_FOREACH(ptr, &chain->nat, _next) { 570 if (ptr->lib->logDesc == NULL) --- 55 unchanged lines hidden (view full) --- 626 627 /* init ipfw hooks */ 628 ipfw_nat_ptr = ipfw_nat; 629 lookup_nat_ptr = lookup_nat; 630 ipfw_nat_cfg_ptr = ipfw_nat_cfg; 631 ipfw_nat_del_ptr = ipfw_nat_del; 632 ipfw_nat_get_cfg_ptr = ipfw_nat_get_cfg; 633 ipfw_nat_get_log_ptr = ipfw_nat_get_log; | 1090 1091 chain = &V_layer3_chain; 1092 1093 IPFW_RLOCK(chain); 1094 /* one pass to count, one to copy the data */ 1095 i = 0; 1096 LIST_FOREACH(ptr, &chain->nat, _next) { 1097 if (ptr->lib->logDesc == NULL) --- 55 unchanged lines hidden (view full) --- 1153 1154 /* init ipfw hooks */ 1155 ipfw_nat_ptr = ipfw_nat; 1156 lookup_nat_ptr = lookup_nat; 1157 ipfw_nat_cfg_ptr = ipfw_nat_cfg; 1158 ipfw_nat_del_ptr = ipfw_nat_del; 1159 ipfw_nat_get_cfg_ptr = ipfw_nat_get_cfg; 1160 ipfw_nat_get_log_ptr = ipfw_nat_get_log; |
1161 IPFW_ADD_SOPT_HANDLER(1, scodes); |
|
634 635 ifaddr_event_tag = EVENTHANDLER_REGISTER(ifaddr_event, ifaddr_change, 636 NULL, EVENTHANDLER_PRI_ANY); 637} 638 639static void 640ipfw_nat_destroy(void) 641{ 642 643 EVENTHANDLER_DEREGISTER(ifaddr_event, ifaddr_event_tag); 644 /* deregister ipfw_nat */ | 1162 1163 ifaddr_event_tag = EVENTHANDLER_REGISTER(ifaddr_event, ifaddr_change, 1164 NULL, EVENTHANDLER_PRI_ANY); 1165} 1166 1167static void 1168ipfw_nat_destroy(void) 1169{ 1170 1171 EVENTHANDLER_DEREGISTER(ifaddr_event, ifaddr_event_tag); 1172 /* deregister ipfw_nat */ |
1173 IPFW_DEL_SOPT_HANDLER(1, scodes); |
|
645 ipfw_nat_ptr = NULL; 646 lookup_nat_ptr = NULL; 647 ipfw_nat_cfg_ptr = NULL; 648 ipfw_nat_del_ptr = NULL; 649 ipfw_nat_get_cfg_ptr = NULL; 650 ipfw_nat_get_log_ptr = NULL; 651} 652 --- 25 unchanged lines hidden (view full) --- 678/* Define startup order. */ 679#define IPFW_NAT_SI_SUB_FIREWALL SI_SUB_PROTO_IFATTACHDOMAIN 680#define IPFW_NAT_MODEVENT_ORDER (SI_ORDER_ANY - 128) /* after ipfw */ 681#define IPFW_NAT_MODULE_ORDER (IPFW_NAT_MODEVENT_ORDER + 1) 682#define IPFW_NAT_VNET_ORDER (IPFW_NAT_MODEVENT_ORDER + 2) 683 684DECLARE_MODULE(ipfw_nat, ipfw_nat_mod, IPFW_NAT_SI_SUB_FIREWALL, SI_ORDER_ANY); 685MODULE_DEPEND(ipfw_nat, libalias, 1, 1, 1); | 1174 ipfw_nat_ptr = NULL; 1175 lookup_nat_ptr = NULL; 1176 ipfw_nat_cfg_ptr = NULL; 1177 ipfw_nat_del_ptr = NULL; 1178 ipfw_nat_get_cfg_ptr = NULL; 1179 ipfw_nat_get_log_ptr = NULL; 1180} 1181 --- 25 unchanged lines hidden (view full) --- 1207/* Define startup order. */ 1208#define IPFW_NAT_SI_SUB_FIREWALL SI_SUB_PROTO_IFATTACHDOMAIN 1209#define IPFW_NAT_MODEVENT_ORDER (SI_ORDER_ANY - 128) /* after ipfw */ 1210#define IPFW_NAT_MODULE_ORDER (IPFW_NAT_MODEVENT_ORDER + 1) 1211#define IPFW_NAT_VNET_ORDER (IPFW_NAT_MODEVENT_ORDER + 2) 1212 1213DECLARE_MODULE(ipfw_nat, ipfw_nat_mod, IPFW_NAT_SI_SUB_FIREWALL, SI_ORDER_ANY); 1214MODULE_DEPEND(ipfw_nat, libalias, 1, 1, 1); |
686MODULE_DEPEND(ipfw_nat, ipfw, 2, 2, 2); | 1215MODULE_DEPEND(ipfw_nat, ipfw, 3, 3, 3); |
687MODULE_VERSION(ipfw_nat, 1); 688 689SYSINIT(ipfw_nat_init, IPFW_NAT_SI_SUB_FIREWALL, IPFW_NAT_MODULE_ORDER, 690 ipfw_nat_init, NULL); 691VNET_SYSINIT(vnet_ipfw_nat_init, IPFW_NAT_SI_SUB_FIREWALL, IPFW_NAT_VNET_ORDER, 692 vnet_ipfw_nat_init, NULL); 693 694SYSUNINIT(ipfw_nat_destroy, IPFW_NAT_SI_SUB_FIREWALL, IPFW_NAT_MODULE_ORDER, 695 ipfw_nat_destroy, NULL); 696VNET_SYSUNINIT(vnet_ipfw_nat_uninit, IPFW_NAT_SI_SUB_FIREWALL, 697 IPFW_NAT_VNET_ORDER, vnet_ipfw_nat_uninit, NULL); 698 699/* end of file */ | 1216MODULE_VERSION(ipfw_nat, 1); 1217 1218SYSINIT(ipfw_nat_init, IPFW_NAT_SI_SUB_FIREWALL, IPFW_NAT_MODULE_ORDER, 1219 ipfw_nat_init, NULL); 1220VNET_SYSINIT(vnet_ipfw_nat_init, IPFW_NAT_SI_SUB_FIREWALL, IPFW_NAT_VNET_ORDER, 1221 vnet_ipfw_nat_init, NULL); 1222 1223SYSUNINIT(ipfw_nat_destroy, IPFW_NAT_SI_SUB_FIREWALL, IPFW_NAT_MODULE_ORDER, 1224 ipfw_nat_destroy, NULL); 1225VNET_SYSUNINIT(vnet_ipfw_nat_uninit, IPFW_NAT_SI_SUB_FIREWALL, 1226 IPFW_NAT_VNET_ORDER, vnet_ipfw_nat_uninit, NULL); 1227 1228/* end of file */ |