diff options
author | ae <ae@FreeBSD.org> | 2011-06-14 13:35:24 +0000 |
---|---|---|
committer | ae <ae@FreeBSD.org> | 2011-06-14 13:35:24 +0000 |
commit | a060389e5b178c7324442c0723886c8fda798998 (patch) | |
tree | 2c079dd50524382ccfa62d936bc012d4c0f8795b /sbin/ipfw | |
parent | 7b7c6f4e74ea94ae75d0f52366eaf6a8ccd0022e (diff) | |
download | FreeBSD-src-a060389e5b178c7324442c0723886c8fda798998.zip FreeBSD-src-a060389e5b178c7324442c0723886c8fda798998.tar.gz |
Implement "global" mode for ipfw nat. It is similar to natd(8)
"globalport" option for multiple NAT instances.
If ipfw rule contains "global" keyword instead of nat_number, then
for each outgoing packet ipfw_nat looks up translation state in all
configured nat instances. If an entry is found, packet aliased
according to that entry, otherwise packet is passed unchanged.
User can specify "skip_global" option in NAT configuration to exclude
an instance from the lookup in global mode.
PR: kern/157867
Submitted by: Alexander V. Chernikov (previous version)
Tested by: Eugene Grosbein
Diffstat (limited to 'sbin/ipfw')
-rw-r--r-- | sbin/ipfw/ipfw.8 | 23 | ||||
-rw-r--r-- | sbin/ipfw/ipfw2.c | 18 | ||||
-rw-r--r-- | sbin/ipfw/ipfw2.h | 1 | ||||
-rw-r--r-- | sbin/ipfw/nat.c | 10 |
4 files changed, 45 insertions, 7 deletions
diff --git a/sbin/ipfw/ipfw.8 b/sbin/ipfw/ipfw.8 index fa9c543..4a22320 100644 --- a/sbin/ipfw/ipfw.8 +++ b/sbin/ipfw/ipfw.8 @@ -1,7 +1,7 @@ .\" .\" $FreeBSD$ .\" -.Dd May 30, 2011 +.Dd June 14, 2011 .Dt IPFW 8 .Os .Sh NAME @@ -2435,6 +2435,27 @@ Reset table of the packet aliasing engine on address change. Reverse the way libalias handles aliasing. .It Cm proxy_only Obey transparent proxy rules only, packet aliasing is not performed. +.It Cm skip_global +Skip instance in case of global state lookup (see below). +.El +.Pp +Some specials value can be supplied instead of +.Va nat_number: +.Bl -tag -width indent +.It Cm global +Looks up translation state in all configured nat instances. +If an entry is found, packet is aliased according to that entry. +If no entry was found in any of the instances, packet is passed unchanged, +and no new entry will be created. +See section +.Sx MULTIPLE INSTANCES +in +.Xr natd 8 +for more information. +.It Cm tablearg +Uses argument supplied in lookup table. See +.Sx LOOKUP TABLES +section below for more information on lookup tables. .El .Pp To let the packet continue after being (de)aliased, set the sysctl variable diff --git a/sbin/ipfw/ipfw2.c b/sbin/ipfw/ipfw2.c index 3e85de3..97d98a3 100644 --- a/sbin/ipfw/ipfw2.c +++ b/sbin/ipfw/ipfw2.c @@ -1121,8 +1121,11 @@ show_ipfw(struct ip_fw *rule, int pcwidth, int bcwidth) break; case O_NAT: - PRINT_UINT_ARG("nat ", cmd->arg1); - break; + if (cmd->arg1 != 0) + PRINT_UINT_ARG("nat ", cmd->arg1); + else + printf("nat global"); + break; case O_SETFIB: PRINT_UINT_ARG("setfib ", cmd->arg1); @@ -2738,9 +2741,14 @@ ipfw_add(char *av[]) break; case TOK_NAT: - action->opcode = O_NAT; - action->len = F_INSN_SIZE(ipfw_insn_nat); - goto chkarg; + action->opcode = O_NAT; + action->len = F_INSN_SIZE(ipfw_insn_nat); + if (_substrcmp(*av, "global") == 0) { + action->arg1 = 0; + av++; + break; + } else + goto chkarg; case TOK_QUEUE: action->opcode = O_QUEUE; diff --git a/sbin/ipfw/ipfw2.h b/sbin/ipfw/ipfw2.h index c9f8687..9562f32 100644 --- a/sbin/ipfw/ipfw2.h +++ b/sbin/ipfw/ipfw2.h @@ -178,6 +178,7 @@ enum tokens { TOK_DENY_INC, TOK_SAME_PORTS, TOK_UNREG_ONLY, + TOK_SKIP_GLOBAL, TOK_RESET_ADDR, TOK_ALIAS_REV, TOK_PROXY_ONLY, diff --git a/sbin/ipfw/nat.c b/sbin/ipfw/nat.c index e91c6ec..6f8c39f 100644 --- a/sbin/ipfw/nat.c +++ b/sbin/ipfw/nat.c @@ -53,6 +53,7 @@ static struct _s_x nat_params[] = { { "deny_in", TOK_DENY_INC }, { "same_ports", TOK_SAME_PORTS }, { "unreg_only", TOK_UNREG_ONLY }, + { "skip_global", TOK_SKIP_GLOBAL }, { "reset", TOK_RESET_ADDR }, { "reverse", TOK_ALIAS_REV }, { "proxy_only", TOK_PROXY_ONLY }, @@ -628,6 +629,9 @@ print_nat_config(unsigned char *buf) } else if (n->mode & PKT_ALIAS_SAME_PORTS) { printf(" same_ports"); n->mode &= ~PKT_ALIAS_SAME_PORTS; + } else if (n->mode & PKT_ALIAS_SKIP_GLOBAL) { + printf(" skip_global"); + n->mode &= ~PKT_ALIAS_SKIP_GLOBAL; } else if (n->mode & PKT_ALIAS_UNREGISTERED_ONLY) { printf(" unreg_only"); n->mode &= ~PKT_ALIAS_UNREGISTERED_ONLY; @@ -746,10 +750,11 @@ ipfw_config_nat(int ac, char **av) case TOK_IP: case TOK_IF: ac1--; av1++; - break; + break; case TOK_ALOG: case TOK_DENY_INC: case TOK_SAME_PORTS: + case TOK_SKIP_GLOBAL: case TOK_UNREG_ONLY: case TOK_RESET_ADDR: case TOK_ALIAS_REV: @@ -821,6 +826,9 @@ ipfw_config_nat(int ac, char **av) case TOK_UNREG_ONLY: n->mode |= PKT_ALIAS_UNREGISTERED_ONLY; break; + case TOK_SKIP_GLOBAL: + n->mode |= PKT_ALIAS_SKIP_GLOBAL; + break; case TOK_RESET_ADDR: n->mode |= PKT_ALIAS_RESET_ON_ADDR_CHANGE; break; |