The following reply was made to PR kern/157867; it has been noted by GNATS.

From: dfil...@freebsd.org (dfilter service)
To: bug-follo...@freebsd.org
Cc:  
Subject: Re: kern/157867: commit references a PR
Date: Thu, 28 Jul 2011 10:10:49 +0000 (UTC)

 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
 _______________________________________________
 svn-src-...@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
 
_______________________________________________
freebsd-ipfw@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-ipfw
To unsubscribe, send any mail to "freebsd-ipfw-unsubscr...@freebsd.org"

Reply via email to