kern/157867: commit references a PR
dfilter service
dfilter at FreeBSD.ORG
Tue Jun 14 13:40:15 UTC 2011
The following reply was made to PR kern/157867; it has been noted by GNATS.
From: dfilter at FreeBSD.ORG (dfilter service)
To: bug-followup at FreeBSD.org
Cc:
Subject: Re: kern/157867: commit references a PR
Date: Tue, 14 Jun 2011 13:35:34 +0000 (UTC)
Author: ae
Date: Tue Jun 14 13:35:24 2011
New Revision: 223080
URL: http://svn.freebsd.org/changeset/base/223080
Log:
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
Modified:
head/sbin/ipfw/ipfw.8
head/sbin/ipfw/ipfw2.c
head/sbin/ipfw/ipfw2.h
head/sbin/ipfw/nat.c
head/sys/netinet/ipfw/ip_fw2.c
head/sys/netinet/ipfw/ip_fw_nat.c
head/sys/netinet/libalias/alias.h
Modified: head/sbin/ipfw/ipfw.8
==============================================================================
--- head/sbin/ipfw/ipfw.8 Tue Jun 14 13:02:26 2011 (r223079)
+++ head/sbin/ipfw/ipfw.8 Tue Jun 14 13:35:24 2011 (r223080)
@@ -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 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: head/sbin/ipfw/ipfw2.c
==============================================================================
--- head/sbin/ipfw/ipfw2.c Tue Jun 14 13:02:26 2011 (r223079)
+++ head/sbin/ipfw/ipfw2.c Tue Jun 14 13:35:24 2011 (r223080)
@@ -1121,8 +1121,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);
@@ -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;
Modified: head/sbin/ipfw/ipfw2.h
==============================================================================
--- head/sbin/ipfw/ipfw2.h Tue Jun 14 13:02:26 2011 (r223079)
+++ head/sbin/ipfw/ipfw2.h Tue Jun 14 13:35:24 2011 (r223080)
@@ -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: head/sbin/ipfw/nat.c
==============================================================================
--- head/sbin/ipfw/nat.c Tue Jun 14 13:02:26 2011 (r223079)
+++ head/sbin/ipfw/nat.c Tue Jun 14 13:35:24 2011 (r223080)
@@ -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;
Modified: head/sys/netinet/ipfw/ip_fw2.c
==============================================================================
--- head/sys/netinet/ipfw/ip_fw2.c Tue Jun 14 13:02:26 2011 (r223079)
+++ head/sys/netinet/ipfw/ip_fw2.c Tue Jun 14 13:35:24 2011 (r223080)
@@ -2194,6 +2194,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: head/sys/netinet/ipfw/ip_fw_nat.c
==============================================================================
--- head/sys/netinet/ipfw/ip_fw_nat.c Tue Jun 14 13:02:26 2011 (r223079)
+++ head/sys/netinet/ipfw/ip_fw_nat.c Tue Jun 14 13:35:24 2011 (r223080)
@@ -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: head/sys/netinet/libalias/alias.h
==============================================================================
--- head/sys/netinet/libalias/alias.h Tue Jun 14 13:02:26 2011 (r223079)
+++ head/sys/netinet/libalias/alias.h Tue Jun 14 13:35:24 2011 (r223080)
@@ -220,6 +220,12 @@ struct mbuf *m_megapullup(struct mbuf
#define PKT_ALIAS_PUNCH_FW 0x100
#endif
+/*
+ * 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
_______________________________________________
svn-src-all at freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscribe at freebsd.org"
More information about the freebsd-ipfw
mailing list