Date: Thu, 28 Jul 2011 10:10:39 +0000 (UTC) From: "Andrey V. Elsukov" <ae@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org Subject: svn commit: r224473 - in stable/8: sbin/ipfw sys/netinet/ipfw sys/netinet/libalias Message-ID: <201107281010.p6SAAdV2095597@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: ae Date: Thu Jul 28 10:10:39 2011 New Revision: 224473 URL: http://svn.freebsd.org/changeset/base/224473 Log: MFC r223080: 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) Modified: stable/8/sbin/ipfw/ipfw.8 stable/8/sbin/ipfw/ipfw2.c stable/8/sbin/ipfw/ipfw2.h stable/8/sbin/ipfw/nat.c stable/8/sys/netinet/ipfw/ip_fw2.c stable/8/sys/netinet/ipfw/ip_fw_nat.c stable/8/sys/netinet/libalias/alias.h Directory Properties: stable/8/sbin/ipfw/ (props changed) stable/8/sys/ (props changed) stable/8/sys/amd64/include/xen/ (props changed) stable/8/sys/cddl/contrib/opensolaris/ (props changed) stable/8/sys/contrib/dev/acpica/ (props changed) stable/8/sys/contrib/pf/ (props changed) stable/8/sys/geom/label/ (props changed) Modified: stable/8/sbin/ipfw/ipfw.8 ============================================================================== --- stable/8/sbin/ipfw/ipfw.8 Thu Jul 28 09:27:01 2011 (r224472) +++ stable/8/sbin/ipfw/ipfw.8 Thu Jul 28 10:10:39 2011 (r224473) @@ -1,7 +1,7 @@ .\" .\" $FreeBSD$ .\" -.Dd May 30, 2011 +.Dd June 14, 2011 .Dt IPFW 8 .Os .Sh NAME @@ -2422,6 +2422,27 @@ Reset table of the packet aliasing engin 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 Modified: stable/8/sbin/ipfw/ipfw2.c ============================================================================== --- stable/8/sbin/ipfw/ipfw2.c Thu Jul 28 09:27:01 2011 (r224472) +++ stable/8/sbin/ipfw/ipfw2.c Thu Jul 28 10:10:39 2011 (r224473) @@ -1112,8 +1112,11 @@ show_ipfw(struct ip_fw *rule, int pcwidt 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); @@ -2728,9 +2731,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; Modified: stable/8/sbin/ipfw/ipfw2.h ============================================================================== --- stable/8/sbin/ipfw/ipfw2.h Thu Jul 28 09:27:01 2011 (r224472) +++ stable/8/sbin/ipfw/ipfw2.h Thu Jul 28 10:10:39 2011 (r224473) @@ -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, Modified: stable/8/sbin/ipfw/nat.c ============================================================================== --- stable/8/sbin/ipfw/nat.c Thu Jul 28 09:27:01 2011 (r224472) +++ stable/8/sbin/ipfw/nat.c Thu Jul 28 10:10:39 2011 (r224473) @@ -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 }, @@ -638,6 +639,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; @@ -760,10 +764,11 @@ ipfw_config_nat(int ac, char **av) 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: @@ -856,6 +861,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; Modified: stable/8/sys/netinet/ipfw/ip_fw2.c ============================================================================== --- stable/8/sys/netinet/ipfw/ip_fw2.c Thu Jul 28 09:27:01 2011 (r224472) +++ stable/8/sys/netinet/ipfw/ip_fw2.c Thu Jul 28 10:10:39 2011 (r224473) @@ -2128,6 +2128,13 @@ do { \ int nat_id; set_match(args, f_pos, chain); + /* Check if this is 'global' nat rule */ + if (cmd->arg1 == 0) { + retval = ipfw_nat_ptr(args, NULL, m); + l = 0; + done = 1; + break; + } t = ((ipfw_insn_nat *)cmd)->nat; if (t == NULL) { nat_id = (cmd->arg1 == IP_FW_TABLEARG) ? Modified: stable/8/sys/netinet/ipfw/ip_fw_nat.c ============================================================================== --- stable/8/sys/netinet/ipfw/ip_fw_nat.c Thu Jul 28 09:27:01 2011 (r224472) +++ stable/8/sys/netinet/ipfw/ip_fw_nat.c Thu Jul 28 10:10:39 2011 (r224473) @@ -207,7 +207,8 @@ ipfw_nat(struct ip_fw_args *args, struct struct mbuf *mcl; struct ip *ip; /* XXX - libalias duct tape */ - int ldt, retval; + int ldt, retval, found; + struct ip_fw_chain *chain; char *c; ldt = 0; @@ -256,12 +257,44 @@ ipfw_nat(struct ip_fw_args *args, struct ldt = 1; c = mtod(mcl, char *); - if (args->oif == NULL) - retval = LibAliasIn(t->lib, c, - mcl->m_len + M_TRAILINGSPACE(mcl)); - else - retval = LibAliasOut(t->lib, c, - mcl->m_len + M_TRAILINGSPACE(mcl)); + + /* Check if this is 'global' instance */ + if (t == NULL) { + if (args->oif == NULL) { + /* Wrong direction, skip processing */ + args->m = mcl; + return (IP_FW_NAT); + } + + found = 0; + chain = &V_layer3_chain; + IPFW_RLOCK(chain); + /* Check every nat entry... */ + LIST_FOREACH(t, &chain->nat, _next) { + if ((t->mode & PKT_ALIAS_SKIP_GLOBAL) != 0) + continue; + retval = LibAliasOutTry(t->lib, c, + mcl->m_len + M_TRAILINGSPACE(mcl), 0); + if (retval == PKT_ALIAS_OK) { + /* Nat instance recognises state */ + found = 1; + break; + } + } + IPFW_RUNLOCK(chain); + if (found != 1) { + /* No instance found, return ignore */ + args->m = mcl; + return (IP_FW_NAT); + } + } else { + if (args->oif == NULL) + retval = LibAliasIn(t->lib, c, + mcl->m_len + M_TRAILINGSPACE(mcl)); + else + retval = LibAliasOut(t->lib, c, + mcl->m_len + M_TRAILINGSPACE(mcl)); + } /* * We drop packet when: @@ -274,7 +307,7 @@ ipfw_nat(struct ip_fw_args *args, struct if (retval == PKT_ALIAS_ERROR || (args->oif == NULL && (retval == PKT_ALIAS_UNRESOLVED_FRAGMENT || (retval == PKT_ALIAS_IGNORED && - (t->lib->packetAliasMode & PKT_ALIAS_DENY_INCOMING) != 0)))) { + (t->mode & PKT_ALIAS_DENY_INCOMING) != 0)))) { /* XXX - should i add some logging? */ m_free(mcl); args->m = NULL; Modified: stable/8/sys/netinet/libalias/alias.h ============================================================================== --- stable/8/sys/netinet/libalias/alias.h Thu Jul 28 09:27:01 2011 (r224472) +++ stable/8/sys/netinet/libalias/alias.h Thu Jul 28 10:10:39 2011 (r224473) @@ -220,6 +220,12 @@ struct mbuf *m_megapullup(struct mbuf */ #define PKT_ALIAS_REVERSE 0x80 +/* + * If PKT_ALIAS_SKIP_GLOBAL is set, nat instance is not checked for matching + * states in 'ipfw nat global' rule. + */ +#define PKT_ALIAS_SKIP_GLOBAL 0x200 + /* Function return codes. */ #define PKT_ALIAS_ERROR -1 #define PKT_ALIAS_OK 1
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201107281010.p6SAAdV2095597>