Author: ae
Date: Mon Mar 18 14:00:19 2019
New Revision: 345275
URL: https://svnweb.freebsd.org/changeset/base/345275

Log:
  Revert r345274. It appears that not all 32-bit architectures have
  necessary CK primitives.

Modified:
  head/sbin/ipfw/ipfw.8
  head/sbin/ipfw/ipfw2.h
  head/sbin/ipfw/nat64lsn.c
  head/sys/conf/files
  head/sys/modules/ipfw_nat64/Makefile
  head/sys/netinet6/ip_fw_nat64.h
  head/sys/netpfil/ipfw/nat64/nat64lsn.c
  head/sys/netpfil/ipfw/nat64/nat64lsn.h
  head/sys/netpfil/ipfw/nat64/nat64lsn_control.c

Modified: head/sbin/ipfw/ipfw.8
==============================================================================
--- head/sbin/ipfw/ipfw.8       Mon Mar 18 12:59:08 2019        (r345274)
+++ head/sbin/ipfw/ipfw.8       Mon Mar 18 14:00:19 2019        (r345275)
@@ -3300,7 +3300,6 @@ See
 .Sx SYSCTL VARIABLES
 for more info.
 .Sh IPv6/IPv4 NETWORK ADDRESS AND PROTOCOL TRANSLATION
-.Ss Stateful translation
 .Nm
 supports in-kernel IPv6/IPv4 network address and protocol translation.
 Stateful NAT64 translation allows IPv6-only clients to contact IPv4 servers
@@ -3318,8 +3317,7 @@ to be able use stateful NAT64 translator.
 Stateful NAT64 uses a bunch of memory for several types of objects.
 When IPv6 client initiates connection, NAT64 translator creates a host entry
 in the states table.
-Each host entry uses preallocated IPv4 alias entry.
-Each alias entry has a number of ports group entries allocated on demand.
+Each host entry has a number of ports group entries allocated on demand.
 Ports group entries contains connection state entries.
 There are several options to control limits and lifetime for these objects.
 .Pp
@@ -3339,11 +3337,6 @@ First time an original packet is handled and consumed 
 and then it is handled again as translated packet.
 This behavior can be changed by sysctl variable 
 .Va net.inet.ip.fw.nat64_direct_output .
-Also translated packet can be tagged using
-.Cm tag
-rule action, and then matched by
-.Cm tagged
-opcode to avoid loops and extra overhead.
 .Pp
 The stateful NAT64 configuration command is the following:
 .Bd -ragged -offset indent
@@ -3371,16 +3364,15 @@ to represent IPv4 addresses. This IPv6 prefix should b
 The translator implementation follows RFC6052, that restricts the length of
 prefixes to one of following: 32, 40, 48, 56, 64, or 96.
 The Well-Known IPv6 Prefix 64:ff9b:: must be 96 bits long.
-The special
-.Ar ::/length
-prefix can be used to handle several IPv6 prefixes with one NAT64 instance.
-The NAT64 instance will determine a destination IPv4 address from prefix
-.Ar length .
-.It Cm states_chunks Ar number
-The number of states chunks in single ports group.
-Each ports group by default can keep 64 state entries in single chunk.
-The above value affects the maximum number of states that can be associated 
with single IPv4 alias address and port.
-The value must be power of 2, and up to 128.
+.It Cm max_ports Ar number
+Maximum number of ports reserved for upper level protocols to one IPv6 client.
+All reserved ports are divided into chunks between supported protocols.
+The number of connections from one IPv6 client is limited by this option.
+Note that closed TCP connections still remain in the list of connections until
+.Cm tcp_close_age
+interval will not expire.
+Default value is
+.Ar 2048 .
 .It Cm host_del_age Ar seconds
 The number of seconds until the host entry for a IPv6 client will be deleted
 and all its resources will be released due to inactivity.

Modified: head/sbin/ipfw/ipfw2.h
==============================================================================
--- head/sbin/ipfw/ipfw2.h      Mon Mar 18 12:59:08 2019        (r345274)
+++ head/sbin/ipfw/ipfw2.h      Mon Mar 18 14:00:19 2019        (r345275)
@@ -278,7 +278,6 @@ enum tokens {
        TOK_AGG_LEN,
        TOK_AGG_COUNT,
        TOK_MAX_PORTS,
-       TOK_STATES_CHUNKS,
        TOK_JMAXLEN,
        TOK_PORT_RANGE,
        TOK_HOST_DEL_AGE,

Modified: head/sbin/ipfw/nat64lsn.c
==============================================================================
--- head/sbin/ipfw/nat64lsn.c   Mon Mar 18 12:59:08 2019        (r345274)
+++ head/sbin/ipfw/nat64lsn.c   Mon Mar 18 14:00:19 2019        (r345275)
@@ -87,70 +87,68 @@ nat64lsn_print_states(void *buf)
        char sflags[4], *sf, *proto;
        ipfw_obj_header *oh;
        ipfw_obj_data *od;
-       ipfw_nat64lsn_stg_v1 *stg;
-       ipfw_nat64lsn_state_v1 *ste;
+       ipfw_nat64lsn_stg *stg;
+       ipfw_nat64lsn_state *ste;
        uint64_t next_idx;
        int i, sz;
 
        oh = (ipfw_obj_header *)buf;
        od = (ipfw_obj_data *)(oh + 1);
-       stg = (ipfw_nat64lsn_stg_v1 *)(od + 1);
+       stg = (ipfw_nat64lsn_stg *)(od + 1);
        sz = od->head.length - sizeof(*od);
        next_idx = 0;
        while (sz > 0 && next_idx != 0xFF) {
-               next_idx = stg->next.index;
+               next_idx = stg->next_idx;
                sz -= sizeof(*stg);
                if (stg->count == 0) {
                        stg++;
                        continue;
                }
-               /*
-                * NOTE: addresses are in network byte order,
-                * ports are in host byte order.
-                */
+               switch (stg->proto) {
+               case IPPROTO_TCP:
+                       proto = "TCP";
+                       break;
+               case IPPROTO_UDP:
+                       proto = "UDP";
+                       break;
+               case IPPROTO_ICMPV6:
+                       proto = "ICMPv6";
+                       break;
+               }
+               inet_ntop(AF_INET6, &stg->host6, s, sizeof(s));
                inet_ntop(AF_INET, &stg->alias4, a, sizeof(a));
-               ste = (ipfw_nat64lsn_state_v1 *)(stg + 1);
+               ste = (ipfw_nat64lsn_state *)(stg + 1);
                for (i = 0; i < stg->count && sz > 0; i++) {
                        sf = sflags;
-                       inet_ntop(AF_INET6, &ste->host6, s, sizeof(s));
                        inet_ntop(AF_INET, &ste->daddr, f, sizeof(f));
-                       switch (ste->proto) {
-                       case IPPROTO_TCP:
-                               proto = "TCP";
+                       if (stg->proto == IPPROTO_TCP) {
                                if (ste->flags & 0x02)
                                        *sf++ = 'S';
                                if (ste->flags & 0x04)
                                        *sf++ = 'E';
                                if (ste->flags & 0x01)
                                        *sf++ = 'F';
-                               break;
-                       case IPPROTO_UDP:
-                               proto = "UDP";
-                               break;
-                       case IPPROTO_ICMP:
-                               proto = "ICMPv6";
-                               break;
                        }
                        *sf = '\0';
-                       switch (ste->proto) {
+                       switch (stg->proto) {
                        case IPPROTO_TCP:
                        case IPPROTO_UDP:
                                printf("%s:%d\t%s:%d\t%s\t%s\t%d\t%s:%d\n",
                                    s, ste->sport, a, ste->aport, proto,
                                    sflags, ste->idle, f, ste->dport);
                                break;
-                       case IPPROTO_ICMP:
+                       case IPPROTO_ICMPV6:
                                printf("%s\t%s\t%s\t\t%d\t%s\n",
                                    s, a, proto, ste->idle, f);
                                break;
                        default:
                                printf("%s\t%s\t%d\t\t%d\t%s\n",
-                                   s, a, ste->proto, ste->idle, f);
+                                   s, a, stg->proto, ste->idle, f);
                        }
                        ste++;
                        sz -= sizeof(*ste);
                }
-               stg = (ipfw_nat64lsn_stg_v1 *)ste;
+               stg = (ipfw_nat64lsn_stg *)ste;
        }
        return (next_idx);
 }
@@ -176,7 +174,6 @@ nat64lsn_states_cb(ipfw_nat64lsn_cfg *cfg, const char 
                err(EX_OSERR, NULL);
        do {
                oh = (ipfw_obj_header *)buf;
-               oh->opheader.version = 1; /* Force using ov new API */
                od = (ipfw_obj_data *)(oh + 1);
                nat64lsn_fill_ntlv(&oh->ntlv, cfg->name, set);
                od->head.type = IPFW_TLV_OBJDATA;
@@ -366,8 +363,12 @@ nat64lsn_parse_int(const char *arg, const char *desc)
 
 static struct _s_x nat64newcmds[] = {
       { "prefix6",     TOK_PREFIX6 },
+      { "agg_len",     TOK_AGG_LEN }, /* not yet */
+      { "agg_count",   TOK_AGG_COUNT }, /* not yet */
+      { "port_range",  TOK_PORT_RANGE }, /* not yet */
       { "jmaxlen",     TOK_JMAXLEN },
       { "prefix4",     TOK_PREFIX4 },
+      { "max_ports",   TOK_MAX_PORTS },
       { "host_del_age",        TOK_HOST_DEL_AGE },
       { "pg_del_age",  TOK_PG_DEL_AGE },
       { "tcp_syn_age", TOK_TCP_SYN_AGE },
@@ -375,13 +376,10 @@ static struct _s_x nat64newcmds[] = {
       { "tcp_est_age", TOK_TCP_EST_AGE },
       { "udp_age",     TOK_UDP_AGE },
       { "icmp_age",    TOK_ICMP_AGE },
-      { "states_chunks",TOK_STATES_CHUNKS },
       { "log",         TOK_LOG },
       { "-log",                TOK_LOGOFF },
       { "allow_private", TOK_PRIVATE },
       { "-allow_private", TOK_PRIVATEOFF },
-      /* for compatibility with old configurations */
-      { "max_ports",   TOK_MAX_PORTS },        /* unused */
       { NULL, 0 }
 };
 
@@ -438,17 +436,42 @@ nat64lsn_create(const char *name, uint8_t set, int ac,
                        nat64lsn_parse_prefix(*av, AF_INET6, &cfg->prefix6,
                            &cfg->plen6);
                        if (ipfw_check_nat64prefix(&cfg->prefix6,
-                           cfg->plen6) != 0 &&
-                           !IN6_IS_ADDR_UNSPECIFIED(&cfg->prefix6))
+                           cfg->plen6) != 0)
                                errx(EX_USAGE, "Bad prefix6 %s", *av);
 
                        ac--; av++;
                        break;
+#if 0
+               case TOK_AGG_LEN:
+                       NEED1("Aggregation prefix len required");
+                       cfg->agg_prefix_len = nat64lsn_parse_int(*av, opt);
+                       ac--; av++;
+                       break;
+               case TOK_AGG_COUNT:
+                       NEED1("Max per-prefix count required");
+                       cfg->agg_prefix_max = nat64lsn_parse_int(*av, opt);
+                       ac--; av++;
+                       break;
+               case TOK_PORT_RANGE:
+                       NEED1("port range x[:y] required");
+                       if ((p = strchr(*av, ':')) == NULL)
+                               cfg->min_port = (uint16_t)nat64lsn_parse_int(
+                                   *av, opt);
+                       else {
+                               *p++ = '\0';
+                               cfg->min_port = (uint16_t)nat64lsn_parse_int(
+                                   *av, opt);
+                               cfg->max_port = (uint16_t)nat64lsn_parse_int(
+                                   p, opt);
+                       }
+                       ac--; av++;
+                       break;
                case TOK_JMAXLEN:
                        NEED1("job queue length required");
                        cfg->jmaxlen = nat64lsn_parse_int(*av, opt);
                        ac--; av++;
                        break;
+#endif
                case TOK_MAX_PORTS:
                        NEED1("Max per-user ports required");
                        cfg->max_ports = nat64lsn_parse_int(*av, opt);
@@ -496,12 +519,6 @@ nat64lsn_create(const char *name, uint8_t set, int ac,
                            *av, opt);
                        ac--; av++;
                        break;
-               case TOK_STATES_CHUNKS:
-                       NEED1("number of chunks required");
-                       cfg->states_chunks = (uint8_t)nat64lsn_parse_int(
-                           *av, opt);
-                       ac--; av++;
-                       break;
                case TOK_LOG:
                        cfg->flags |= NAT64_LOG;
                        break;
@@ -613,12 +630,6 @@ nat64lsn_config(const char *name, uint8_t set, int ac,
                            *av, opt);
                        ac--; av++;
                        break;
-               case TOK_STATES_CHUNKS:
-                       NEED1("number of chunks required");
-                       cfg->states_chunks = (uint8_t)nat64lsn_parse_int(
-                           *av, opt);
-                       ac--; av++;
-                       break;
                case TOK_LOG:
                        cfg->flags |= NAT64_LOG;
                        break;
@@ -778,24 +789,31 @@ nat64lsn_show_cb(ipfw_nat64lsn_cfg *cfg, const char *n
        printf("nat64lsn %s prefix4 %s/%u", cfg->name, abuf, cfg->plen4);
        inet_ntop(AF_INET6, &cfg->prefix6, abuf, sizeof(abuf));
        printf(" prefix6 %s/%u", abuf, cfg->plen6);
-       if (co.verbose || cfg->states_chunks > 1)
-               printf(" states_chunks %u", cfg->states_chunks);
-       if (co.verbose || cfg->nh_delete_delay != NAT64LSN_HOST_AGE)
+#if 0
+       printf("agg_len %u agg_count %u ", cfg->agg_prefix_len,
+           cfg->agg_prefix_max);
+       if (cfg->min_port != NAT64LSN_PORT_MIN ||
+           cfg->max_port != NAT64LSN_PORT_MAX)
+               printf(" port_range %u:%u", cfg->min_port, cfg->max_port);
+       if (cfg->jmaxlen != NAT64LSN_JMAXLEN)
+               printf(" jmaxlen %u ", cfg->jmaxlen);
+#endif
+       if (cfg->max_ports != NAT64LSN_MAX_PORTS)
+               printf(" max_ports %u", cfg->max_ports);
+       if (cfg->nh_delete_delay != NAT64LSN_HOST_AGE)
                printf(" host_del_age %u", cfg->nh_delete_delay);
-       if (co.verbose || cfg->pg_delete_delay != NAT64LSN_PG_AGE)
+       if (cfg->pg_delete_delay != NAT64LSN_PG_AGE)
                printf(" pg_del_age %u ", cfg->pg_delete_delay);
-       if (co.verbose || cfg->st_syn_ttl != NAT64LSN_TCP_SYN_AGE)
+       if (cfg->st_syn_ttl != NAT64LSN_TCP_SYN_AGE)
                printf(" tcp_syn_age %u", cfg->st_syn_ttl);
-       if (co.verbose || cfg->st_close_ttl != NAT64LSN_TCP_FIN_AGE)
+       if (cfg->st_close_ttl != NAT64LSN_TCP_FIN_AGE)
                printf(" tcp_close_age %u", cfg->st_close_ttl);
-       if (co.verbose || cfg->st_estab_ttl != NAT64LSN_TCP_EST_AGE)
+       if (cfg->st_estab_ttl != NAT64LSN_TCP_EST_AGE)
                printf(" tcp_est_age %u", cfg->st_estab_ttl);
-       if (co.verbose || cfg->st_udp_ttl != NAT64LSN_UDP_AGE)
+       if (cfg->st_udp_ttl != NAT64LSN_UDP_AGE)
                printf(" udp_age %u", cfg->st_udp_ttl);
-       if (co.verbose || cfg->st_icmp_ttl != NAT64LSN_ICMP_AGE)
+       if (cfg->st_icmp_ttl != NAT64LSN_ICMP_AGE)
                printf(" icmp_age %u", cfg->st_icmp_ttl);
-       if (co.verbose || cfg->jmaxlen != NAT64LSN_JMAXLEN)
-               printf(" jmaxlen %u ", cfg->jmaxlen);
        if (cfg->flags & NAT64_LOG)
                printf(" log");
        if (cfg->flags & NAT64_ALLOW_PRIVATE)

Modified: head/sys/conf/files
==============================================================================
--- head/sys/conf/files Mon Mar 18 12:59:08 2019        (r345274)
+++ head/sys/conf/files Mon Mar 18 14:00:19 2019        (r345275)
@@ -4398,9 +4398,9 @@ netpfil/ipfw/nat64/nat64clat.c    optional inet inet6 ipf
 netpfil/ipfw/nat64/nat64clat_control.c optional inet inet6 ipfirewall \
        ipfirewall_nat64
 netpfil/ipfw/nat64/nat64lsn.c  optional inet inet6 ipfirewall \
-       ipfirewall_nat64 compile-with "${NORMAL_C} -I$S/contrib/ck/include"
+       ipfirewall_nat64
 netpfil/ipfw/nat64/nat64lsn_control.c  optional inet inet6 ipfirewall \
-       ipfirewall_nat64 compile-with "${NORMAL_C} -I$S/contrib/ck/include"
+       ipfirewall_nat64
 netpfil/ipfw/nat64/nat64stl.c  optional inet inet6 ipfirewall \
        ipfirewall_nat64
 netpfil/ipfw/nat64/nat64stl_control.c  optional inet inet6 ipfirewall \

Modified: head/sys/modules/ipfw_nat64/Makefile
==============================================================================
--- head/sys/modules/ipfw_nat64/Makefile        Mon Mar 18 12:59:08 2019        
(r345274)
+++ head/sys/modules/ipfw_nat64/Makefile        Mon Mar 18 14:00:19 2019        
(r345275)
@@ -8,6 +8,4 @@ SRCS+=  nat64clat.c nat64clat_control.c
 SRCS+= nat64lsn.c nat64lsn_control.c
 SRCS+= nat64stl.c nat64stl_control.c
 
-CFLAGS+= -I${SRCTOP}/sys/contrib/ck/include
-
 .include <bsd.kmod.mk>

Modified: head/sys/netinet6/ip_fw_nat64.h
==============================================================================
--- head/sys/netinet6/ip_fw_nat64.h     Mon Mar 18 12:59:08 2019        
(r345274)
+++ head/sys/netinet6/ip_fw_nat64.h     Mon Mar 18 14:00:19 2019        
(r345275)
@@ -122,7 +122,7 @@ typedef struct _ipfw_nat64clat_cfg {
 /*
  * NAT64LSN default configuration values
  */
-#define        NAT64LSN_MAX_PORTS      2048    /* Unused */
+#define        NAT64LSN_MAX_PORTS      2048    /* Max number of ports per host 
*/
 #define        NAT64LSN_JMAXLEN        2048    /* Max outstanding requests. */
 #define        NAT64LSN_TCP_SYN_AGE    10      /* State's TTL after SYN 
received. */
 #define        NAT64LSN_TCP_EST_AGE    (2 * 3600) /* TTL for established 
connection */
@@ -135,20 +135,16 @@ typedef struct _ipfw_nat64clat_cfg {
 typedef struct _ipfw_nat64lsn_cfg {
        char            name[64];       /* NAT name                     */
        uint32_t        flags;
-
-       uint32_t        max_ports;      /* Unused */
-       uint32_t        agg_prefix_len; /* Unused */
-       uint32_t        agg_prefix_max; /* Unused */
-
+       uint32_t        max_ports;      /* Max ports per client */
+       uint32_t        agg_prefix_len; /* Prefix length to count */
+       uint32_t        agg_prefix_max; /* Max hosts per agg prefix */
        struct in_addr  prefix4;
        uint16_t        plen4;          /* Prefix length */
        uint16_t        plen6;          /* Prefix length */
        struct in6_addr prefix6;        /* NAT64 prefix */
        uint32_t        jmaxlen;        /* Max jobqueue length */
-
-       uint16_t        min_port;       /* Unused */
-       uint16_t        max_port;       /* Unused */
-
+       uint16_t        min_port;       /* Min port group # to use */
+       uint16_t        max_port;       /* Max port group # to use */
        uint16_t        nh_delete_delay;/* Stale host delete delay */
        uint16_t        pg_delete_delay;/* Stale portgroup delete delay */
        uint16_t        st_syn_ttl;     /* TCP syn expire */
@@ -157,7 +153,7 @@ typedef struct _ipfw_nat64lsn_cfg {
        uint16_t        st_udp_ttl;     /* UDP expire */
        uint16_t        st_icmp_ttl;    /* ICMP expire */
        uint8_t         set;            /* Named instance set [0..31] */
-       uint8_t         states_chunks;  /* Number of states chunks per PG */
+       uint8_t         spare;
 } ipfw_nat64lsn_cfg;
 
 typedef struct _ipfw_nat64lsn_state {
@@ -181,30 +177,5 @@ typedef struct _ipfw_nat64lsn_stg {
        uint32_t        spare2;
 } ipfw_nat64lsn_stg;
 
-typedef struct _ipfw_nat64lsn_state_v1 {
-       struct in6_addr host6;          /* Bound IPv6 host */
-       struct in_addr  daddr;          /* Remote IPv4 address */
-       uint16_t        dport;          /* Remote destination port */
-       uint16_t        aport;          /* Local alias port */
-       uint16_t        sport;          /* Source port */
-       uint16_t        spare;
-       uint16_t        idle;           /* Last used time */
-       uint8_t         flags;          /* State flags */
-       uint8_t         proto;          /* protocol */
-} ipfw_nat64lsn_state_v1;
-
-typedef struct _ipfw_nat64lsn_stg_v1 {
-       union nat64lsn_pgidx {
-               uint64_t        index;
-               struct {
-                       uint8_t         chunk;  /* states chunk */
-                       uint8_t         proto;  /* protocol */
-                       uint16_t        port;   /* base port */
-                       in_addr_t       addr;   /* alias address */
-               };
-       } next;                         /* next state index */
-       struct in_addr  alias4;         /* IPv4 alias address */
-       uint32_t        count;          /* Number of states */
-} ipfw_nat64lsn_stg_v1;
-
 #endif /* _NETINET6_IP_FW_NAT64_H_ */
+

Modified: head/sys/netpfil/ipfw/nat64/nat64lsn.c
==============================================================================
--- head/sys/netpfil/ipfw/nat64/nat64lsn.c      Mon Mar 18 12:59:08 2019        
(r345274)
+++ head/sys/netpfil/ipfw/nat64/nat64lsn.c      Mon Mar 18 14:00:19 2019        
(r345275)
@@ -33,17 +33,16 @@ __FBSDID("$FreeBSD$");
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/counter.h>
-#include <sys/ck.h>
-#include <sys/epoch.h>
 #include <sys/errno.h>
-#include <sys/hash.h>
 #include <sys/kernel.h>
 #include <sys/lock.h>
 #include <sys/malloc.h>
 #include <sys/mbuf.h>
 #include <sys/module.h>
 #include <sys/rmlock.h>
+#include <sys/rwlock.h>
 #include <sys/socket.h>
+#include <sys/queue.h>
 #include <sys/syslog.h>
 #include <sys/sysctl.h>
 
@@ -72,22 +71,17 @@ __FBSDID("$FreeBSD$");
 
 MALLOC_DEFINE(M_NAT64LSN, "NAT64LSN", "NAT64LSN");
 
-static epoch_t nat64lsn_epoch;
-#define        NAT64LSN_EPOCH_ENTER(et)  epoch_enter_preempt(nat64lsn_epoch, 
&(et))
-#define        NAT64LSN_EPOCH_EXIT(et)   epoch_exit_preempt(nat64lsn_epoch, 
&(et))
-#define        NAT64LSN_EPOCH_WAIT()     epoch_wait_preempt(nat64lsn_epoch)
-#define        NAT64LSN_EPOCH_ASSERT()   MPASS(in_epoch(nat64lsn_epoch))
-#define        NAT64LSN_EPOCH_CALL(c, f) epoch_call(nat64lsn_epoch, (c), (f))
+static void nat64lsn_periodic(void *data);
+#define        PERIODIC_DELAY  4
+static uint8_t nat64lsn_proto_map[256];
+uint8_t nat64lsn_rproto_map[NAT_MAX_PROTO];
 
-static uma_zone_t nat64lsn_host_zone;
-static uma_zone_t nat64lsn_pgchunk_zone;
-static uma_zone_t nat64lsn_pg_zone;
-static uma_zone_t nat64lsn_aliaslink_zone;
-static uma_zone_t nat64lsn_state_zone;
-static uma_zone_t nat64lsn_job_zone;
+#define        NAT64_FLAG_FIN          0x01    /* FIN was seen */
+#define        NAT64_FLAG_SYN          0x02    /* First syn in->out */
+#define        NAT64_FLAG_ESTAB        0x04    /* Packet with Ack */
+#define        NAT64_FLAGS_TCP (NAT64_FLAG_SYN|NAT64_FLAG_ESTAB|NAT64_FLAG_FIN)
 
-static void nat64lsn_periodic(void *data);
-#define        PERIODIC_DELAY          4
+#define        NAT64_FLAG_RDR          0x80    /* Port redirect */
 #define        NAT64_LOOKUP(chain, cmd)        \
        (struct nat64lsn_cfg *)SRV_OBJECT((chain), (cmd)->arg1)
 /*
@@ -97,33 +91,25 @@ static void nat64lsn_periodic(void *data);
 enum nat64lsn_jtype {
        JTYPE_NEWHOST = 1,
        JTYPE_NEWPORTGROUP,
-       JTYPE_DESTROY,
+       JTYPE_DELPORTGROUP,
 };
 
 struct nat64lsn_job_item {
-       STAILQ_ENTRY(nat64lsn_job_item) entries;
+       TAILQ_ENTRY(nat64lsn_job_item)  next;
        enum nat64lsn_jtype     jtype;
-
-       union {
-               struct { /* used by JTYPE_NEWHOST, JTYPE_NEWPORTGROUP */
-                       struct mbuf             *m;
-                       struct nat64lsn_host    *host;
-                       struct nat64lsn_state   *state;
-                       uint32_t                src6_hval;
-                       uint32_t                state_hval;
-                       struct ipfw_flow_id     f_id;
-                       in_addr_t               faddr;
-                       uint16_t                port;
-                       uint8_t                 proto;
-                       uint8_t                 done;
-               };
-               struct { /* used by JTYPE_DESTROY */
-                       struct nat64lsn_hosts_slist     hosts;
-                       struct nat64lsn_pg_slist        portgroups;
-                       struct nat64lsn_pgchunk         *pgchunk;
-                       struct epoch_context            epoch_ctx;
-               };
-       };
+       struct nat64lsn_host    *nh;
+       struct nat64lsn_portgroup       *pg;
+       void                    *spare_idx;
+       struct in6_addr         haddr;
+       uint8_t                 nat_proto;
+       uint8_t                 done;
+       int                     needs_idx;
+       int                     delcount;
+       unsigned int            fhash;  /* Flow hash */
+       uint32_t                aaddr;  /* Last used address (net) */
+       struct mbuf             *m;
+       struct ipfw_flow_id     f_id;
+       uint64_t                delmask[NAT64LSN_PGPTRNMASK];
 };
 
 static struct mtx jmtx;
@@ -132,278 +118,143 @@ static struct mtx jmtx;
 #define        JQUEUE_LOCK()           mtx_lock(&jmtx)
 #define        JQUEUE_UNLOCK()         mtx_unlock(&jmtx)
 
-static int nat64lsn_alloc_host(struct nat64lsn_cfg *cfg,
-    struct nat64lsn_job_item *ji);
-static int nat64lsn_alloc_pg(struct nat64lsn_cfg *cfg,
-    struct nat64lsn_job_item *ji);
-static struct nat64lsn_job_item *nat64lsn_create_job(
-    struct nat64lsn_cfg *cfg, int jtype);
 static void nat64lsn_enqueue_job(struct nat64lsn_cfg *cfg,
     struct nat64lsn_job_item *ji);
-static void nat64lsn_job_destroy(epoch_context_t ctx);
-static void nat64lsn_destroy_host(struct nat64lsn_host *host);
-static void nat64lsn_destroy_pg(struct nat64lsn_pg *pg);
+static void nat64lsn_enqueue_jobs(struct nat64lsn_cfg *cfg,
+    struct nat64lsn_job_head *jhead, int jlen);
 
+static struct nat64lsn_job_item *nat64lsn_create_job(struct nat64lsn_cfg *cfg,
+    const struct ipfw_flow_id *f_id, int jtype);
+static int nat64lsn_request_portgroup(struct nat64lsn_cfg *cfg,
+    const struct ipfw_flow_id *f_id, struct mbuf **pm, uint32_t aaddr,
+    int needs_idx);
+static int nat64lsn_request_host(struct nat64lsn_cfg *cfg,
+    const struct ipfw_flow_id *f_id, struct mbuf **pm);
 static int nat64lsn_translate4(struct nat64lsn_cfg *cfg,
-    const struct ipfw_flow_id *f_id, struct mbuf **mp);
+    const struct ipfw_flow_id *f_id, struct mbuf **pm);
 static int nat64lsn_translate6(struct nat64lsn_cfg *cfg,
-    struct ipfw_flow_id *f_id, struct mbuf **mp);
-static int nat64lsn_translate6_internal(struct nat64lsn_cfg *cfg,
-    struct mbuf **mp, struct nat64lsn_state *state, uint8_t flags);
+    struct ipfw_flow_id *f_id, struct mbuf **pm);
 
-#define        NAT64_BIT_TCP_FIN       0       /* FIN was seen */
-#define        NAT64_BIT_TCP_SYN       1       /* First syn in->out */
-#define        NAT64_BIT_TCP_ESTAB     2       /* Packet with Ack */
-#define        NAT64_BIT_READY_IPV4    6       /* state is ready for 
translate4 */
-#define        NAT64_BIT_STALE         7       /* state is going to be expired 
*/
+static int alloc_portgroup(struct nat64lsn_job_item *ji);
+static void destroy_portgroup(struct nat64lsn_portgroup *pg);
+static void destroy_host6(struct nat64lsn_host *nh);
+static int alloc_host6(struct nat64lsn_cfg *cfg, struct nat64lsn_job_item *ji);
 
-#define        NAT64_FLAG_FIN          (1 << NAT64_BIT_TCP_FIN)
-#define        NAT64_FLAG_SYN          (1 << NAT64_BIT_TCP_SYN)
-#define        NAT64_FLAG_ESTAB        (1 << NAT64_BIT_TCP_ESTAB)
-#define        NAT64_FLAGS_TCP (NAT64_FLAG_SYN|NAT64_FLAG_ESTAB|NAT64_FLAG_FIN)
+static int attach_portgroup(struct nat64lsn_cfg *cfg,
+    struct nat64lsn_job_item *ji);
+static int attach_host6(struct nat64lsn_cfg *cfg, struct nat64lsn_job_item 
*ji);
 
-#define        NAT64_FLAG_READY        (1 << NAT64_BIT_READY_IPV4)
-#define        NAT64_FLAG_STALE        (1 << NAT64_BIT_STALE)
 
-static inline uint8_t
-convert_tcp_flags(uint8_t flags)
-{
-       uint8_t result;
+/* XXX tmp */
+static uma_zone_t nat64lsn_host_zone;
+static uma_zone_t nat64lsn_pg_zone;
+static uma_zone_t nat64lsn_pgidx_zone;
 
-       result = flags & (TH_FIN|TH_SYN);
-       result |= (flags & TH_RST) >> 2; /* Treat RST as FIN */
-       result |= (flags & TH_ACK) >> 2; /* Treat ACK as estab */
+static unsigned int nat64lsn_periodic_chkstates(struct nat64lsn_cfg *cfg,
+    struct nat64lsn_host *nh);
 
-       return (result);
-}
+#define        I6_hash(x)              (djb_hash((const unsigned char *)(x), 
16))
+#define        I6_first(_ph, h)        (_ph)[h]
+#define        I6_next(x)              (x)->next
+#define        I6_val(x)               (&(x)->addr)
+#define        I6_cmp(a, b)            IN6_ARE_ADDR_EQUAL(a, b)
+#define        I6_lock(a, b)
+#define        I6_unlock(a, b)
 
-static void
-nat64lsn_log(struct pfloghdr *plog, struct mbuf *m, sa_family_t family,
-    uintptr_t state)
-{
+#define        I6HASH_FIND(_cfg, _res, _a) \
+       CHT_FIND(_cfg->ih, _cfg->ihsize, I6_, _res, _a)
+#define        I6HASH_INSERT(_cfg, _i) \
+       CHT_INSERT_HEAD(_cfg->ih, _cfg->ihsize, I6_, _i)
+#define        I6HASH_REMOVE(_cfg, _res, _tmp, _a)     \
+       CHT_REMOVE(_cfg->ih, _cfg->ihsize, I6_, _res, _tmp, _a)
 
-       memset(plog, 0, sizeof(*plog));
-       plog->length = PFLOG_REAL_HDRLEN;
-       plog->af = family;
-       plog->action = PF_NAT;
-       plog->dir = PF_IN;
-       plog->rulenr = htonl(state >> 32);
-       plog->subrulenr = htonl(state & 0xffffffff);
-       plog->ruleset[0] = '\0';
-       strlcpy(plog->ifname, "NAT64LSN", sizeof(plog->ifname));
-       ipfw_bpf_mtap2(plog, PFLOG_HDRLEN, m);
-}
+#define        I6HASH_FOREACH_SAFE(_cfg, _x, _tmp, _cb, _arg)  \
+       CHT_FOREACH_SAFE(_cfg->ih, _cfg->ihsize, I6_, _x, _tmp, _cb, _arg)
 
-#define        HVAL(p, n, s)   jenkins_hash32((const uint32_t *)(p), (n), (s))
-#define        HOST_HVAL(c, a) HVAL((a),\
-    sizeof(struct in6_addr) / sizeof(uint32_t), (c)->hash_seed)
-#define        HOSTS(c, v)     ((c)->hosts_hash[(v) & ((c)->hosts_hashsize - 
1)])
+#define        HASH_IN4(x)     djb_hash((const unsigned char *)(x), 8)
 
-#define        ALIASLINK_HVAL(c, f)    HVAL(&(f)->dst_ip6,\
-    sizeof(struct in6_addr) * 2 / sizeof(uint32_t), (c)->hash_seed)
-#define        ALIAS_BYHASH(c, v)      \
-    ((c)->aliases[(v) & ((1 << (32 - (c)->plen4)) - 1)])
-static struct nat64lsn_aliaslink*
-nat64lsn_get_aliaslink(struct nat64lsn_cfg *cfg __unused,
-    struct nat64lsn_host *host, const struct ipfw_flow_id *f_id __unused)
+static unsigned
+djb_hash(const unsigned char *h, const int len)
 {
+       unsigned int result = 0;
+       int i;
 
-       /*
-        * We can implement some different algorithms how
-        * select an alias address.
-        * XXX: for now we use first available.
-        */
-       return (CK_SLIST_FIRST(&host->aliases));
+       for (i = 0; i < len; i++)
+               result = 33 * result ^ h[i];
+
+       return (result);
 }
 
-#define        FADDR_CHUNK(p, a)       ((a) & ((p)->chunks_count - 1))
-#define        FREEMASK_CHUNK(p, v)    \
-    ((p)->chunks_count == 1 ? &(p)->freemask : \
-       &((p)->freemask_chunk[FADDR_CHUNK(p, v)]))
-#define        STATES_CHUNK(p, v)      \
-    ((p)->chunks_count == 1 ? (p)->states : \
-       ((p)->states_chunk[FADDR_CHUNK(p, v)]))
-#define        STATE_HVAL(c, d)        HVAL((d), 2, (c)->hash_seed)
-#define        STATE_HASH(h, v)        \
-    ((h)->states_hash[(v) & ((h)->states_hashsize - 1)])
-
-#define        NAT64LSN_TRY_PGCNT      32
-static struct nat64lsn_pg*
-nat64lsn_get_pg(uint32_t *chunkmask, uint32_t *pgmask,
-    struct nat64lsn_pgchunk **chunks, struct nat64lsn_pg **pgptr,
-    uint32_t *pgidx, in_addr_t faddr)
+/*
+static size_t 
+bitmask_size(size_t num, int *level)
 {
-       struct nat64lsn_pg *pg, *oldpg;
-       uint32_t idx, oldidx;
-       int cnt;
+       size_t x;
+       int c;
 
-       cnt = 0;
-       /* First try last used PG */
-       oldpg = pg = ck_pr_load_ptr(pgptr);
-       idx = oldidx = ck_pr_load_32(pgidx);
-       /* If pgidx is out of range, reset it to the first pgchunk */
-       if (!ISSET32(*chunkmask, idx / 32))
-               idx = 0;
-       do {
-               ck_pr_fence_load();
-               if (pg != NULL &&
-                   bitcount64(*FREEMASK_CHUNK(pg, faddr)) > 0) {
-                       /*
-                        * If last used PG has not free states,
-                        * try to update pointer.
-                        * NOTE: it can be already updated by jobs handler,
-                        *       thus we use CAS operation.
-                        */
-                       if (cnt > 0)
-                               ck_pr_cas_ptr(pgptr, oldpg, pg);
-                       return (pg);
-               }
-               /* Stop if idx is out of range */
-               if (!ISSET32(*chunkmask, idx / 32))
-                       break;
+       for (c = 0, x = num; num > 1; num /= 64, c++)
+               ;
 
-               if (ISSET32(pgmask[idx / 32], idx % 32))
-                       pg = ck_pr_load_ptr(
-                           &chunks[idx / 32]->pgptr[idx % 32]);
-               else
-                       pg = NULL;
+       return (x);
+}
 
-               idx++;
-       } while (++cnt < NAT64LSN_TRY_PGCNT);
+static void
+bitmask_prepare(uint64_t *pmask, size_t bufsize, int level)
+{
+       size_t x, z;
 
-       /* If pgidx is out of range, reset it to the first pgchunk */
-       if (!ISSET32(*chunkmask, idx / 32))
-               idx = 0;
-       ck_pr_cas_32(pgidx, oldidx, idx);
-       return (NULL);
+       memset(pmask, 0xFF, bufsize);
+       for (x = 0, z = 1; level > 1; x += z, z *= 64, level--)
+               ;
+       pmask[x] ~= 0x01;
 }
+*/
 
-static struct nat64lsn_state*
-nat64lsn_get_state6to4(struct nat64lsn_cfg *cfg, struct nat64lsn_host *host,
-    const struct ipfw_flow_id *f_id, uint32_t hval, in_addr_t faddr,
-    uint16_t port, uint8_t proto)
+static void
+nat64lsn_log(struct pfloghdr *plog, struct mbuf *m, sa_family_t family,
+    uint32_t n, uint32_t sn)
 {
-       struct nat64lsn_aliaslink *link;
-       struct nat64lsn_state *state;
-       struct nat64lsn_pg *pg;
-       int i, offset;
 
-       NAT64LSN_EPOCH_ASSERT();
-
-       /* Check that we already have state for given arguments */
-       CK_SLIST_FOREACH(state, &STATE_HASH(host, hval), entries) {
-               if (state->proto == proto && state->ip_dst == faddr &&
-                   state->sport == port && state->dport == f_id->dst_port)
-                       return (state);
-       }
-
-       link = nat64lsn_get_aliaslink(cfg, host, f_id);
-       if (link == NULL)
-               return (NULL);
-
-       switch (proto) {
-       case IPPROTO_TCP:
-               pg = nat64lsn_get_pg(
-                   &link->alias->tcp_chunkmask, link->alias->tcp_pgmask,
-                   link->alias->tcp, &link->alias->tcp_pg,
-                   &link->alias->tcp_pgidx, faddr);
-               break;
-       case IPPROTO_UDP:
-               pg = nat64lsn_get_pg(
-                   &link->alias->udp_chunkmask, link->alias->udp_pgmask,
-                   link->alias->udp, &link->alias->udp_pg,
-                   &link->alias->udp_pgidx, faddr);
-               break;
-       case IPPROTO_ICMP:
-               pg = nat64lsn_get_pg(
-                   &link->alias->icmp_chunkmask, link->alias->icmp_pgmask,
-                   link->alias->icmp, &link->alias->icmp_pg,
-                   &link->alias->icmp_pgidx, faddr);
-               break;
-       default:
-               panic("%s: wrong proto %d", __func__, proto);
-       }
-       if (pg == NULL)
-               return (NULL);
-
-       /* Check that PG has some free states */
-       state = NULL;
-       i = bitcount64(*FREEMASK_CHUNK(pg, faddr));
-       while (i-- > 0) {
-               offset = ffsll(*FREEMASK_CHUNK(pg, faddr));
-               if (offset == 0) {
-                       /*
-                        * We lost the race.
-                        * No more free states in this PG.
-                        */
-                       break;
-               }
-
-               /* Lets try to atomically grab the state */
-               if (ck_pr_btr_64(FREEMASK_CHUNK(pg, faddr), offset - 1)) {
-                       state = &STATES_CHUNK(pg, faddr)->state[offset - 1];
-                       /* Initialize */
-                       state->flags = proto != IPPROTO_TCP ? 0 :
-                           convert_tcp_flags(f_id->_flags);
-                       state->proto = proto;
-                       state->aport = pg->base_port + offset - 1;
-                       state->dport = f_id->dst_port;
-                       state->sport = port;
-                       state->ip6_dst = f_id->dst_ip6;
-                       state->ip_dst = faddr;
-                       state->ip_src = link->alias->addr;
-                       state->hval = hval;
-                       state->host = host;
-                       SET_AGE(state->timestamp);
-
-                       /* Insert new state into host's hash table */
-                       HOST_LOCK(host);
-                       CK_SLIST_INSERT_HEAD(&STATE_HASH(host, hval),
-                           state, entries);
-                       host->states_count++;
-                       /*
-                        * XXX: In case if host is going to be expired,
-                        * reset NAT64LSN_DEADHOST flag.
-                        */
-                       host->flags &= ~NAT64LSN_DEADHOST;
-                       HOST_UNLOCK(host);
-                       NAT64STAT_INC(&cfg->base.stats, screated);
-                       /* Mark the state as ready for translate4 */
-                       ck_pr_fence_store();
-                       ck_pr_bts_32(&state->flags, NAT64_BIT_READY_IPV4);
-                       break;
-               }
-       }
-       return (state);
+       memset(plog, 0, sizeof(*plog));
+       plog->length = PFLOG_REAL_HDRLEN;
+       plog->af = family;
+       plog->action = PF_NAT;
+       plog->dir = PF_IN;
+       plog->rulenr = htonl(n);
+       plog->subrulenr = htonl(sn);
+       plog->ruleset[0] = '\0';
+       strlcpy(plog->ifname, "NAT64LSN", sizeof(plog->ifname));
+       ipfw_bpf_mtap2(plog, PFLOG_HDRLEN, m);
 }
-
 /*
  * Inspects icmp packets to see if the message contains different
  * packet header so we need to alter @addr and @port.
  */
 static int
-inspect_icmp_mbuf(struct mbuf **mp, uint8_t *proto, uint32_t *addr,
+inspect_icmp_mbuf(struct mbuf **m, uint8_t *nat_proto, uint32_t *addr,
     uint16_t *port)
 {
-       struct icmp *icmp;
        struct ip *ip;
+       struct tcphdr *tcp;
+       struct udphdr *udp;
+       struct icmphdr *icmp;
        int off;
-       uint8_t inner_proto;
+       uint8_t proto;
 
-       ip = mtod(*mp, struct ip *); /* Outer IP header */
+       ip = mtod(*m, struct ip *); /* Outer IP header */
        off = (ip->ip_hl << 2) + ICMP_MINLEN;
-       if ((*mp)->m_len < off)
-               *mp = m_pullup(*mp, off);
-       if (*mp == NULL)
+       if ((*m)->m_len < off)
+               *m = m_pullup(*m, off);
+       if (*m == NULL)
                return (ENOMEM);
 
-       ip = mtod(*mp, struct ip *); /* Outer IP header */
-       icmp = L3HDR(ip, struct icmp *);
+       ip = mtod(*m, struct ip *); /* Outer IP header */
+       icmp = L3HDR(ip, struct icmphdr *);
        switch (icmp->icmp_type) {
        case ICMP_ECHO:
        case ICMP_ECHOREPLY:
                /* Use icmp ID as distinguisher */
-               *port = ntohs(icmp->icmp_id);
+               *port = ntohs(*((uint16_t *)(icmp + 1)));
                return (0);
        case ICMP_UNREACH:
        case ICMP_TIMXCEED:
@@ -415,133 +266,90 @@ inspect_icmp_mbuf(struct mbuf **mp, uint8_t *proto, ui
         * ICMP_UNREACH and ICMP_TIMXCEED contains IP header + 64 bits
         * of ULP header.
         */
-       if ((*mp)->m_pkthdr.len < off + sizeof(struct ip) + ICMP_MINLEN)
+       if ((*m)->m_pkthdr.len < off + sizeof(struct ip) + ICMP_MINLEN)
                return (EINVAL);
-       if ((*mp)->m_len < off + sizeof(struct ip) + ICMP_MINLEN)
-               *mp = m_pullup(*mp, off + sizeof(struct ip) + ICMP_MINLEN);
-       if (*mp == NULL)
+       if ((*m)->m_len < off + sizeof(struct ip) + ICMP_MINLEN)
+               *m = m_pullup(*m, off + sizeof(struct ip) + ICMP_MINLEN);
+       if (*m == NULL)
                return (ENOMEM);
-       ip = mtodo(*mp, off); /* Inner IP header */
-       inner_proto = ip->ip_p;
+       ip = mtodo(*m, off); /* Inner IP header */
+       proto = ip->ip_p;
        off += ip->ip_hl << 2; /* Skip inner IP header */
        *addr = ntohl(ip->ip_src.s_addr);
-       if ((*mp)->m_len < off + ICMP_MINLEN)
-               *mp = m_pullup(*mp, off + ICMP_MINLEN);
-       if (*mp == NULL)
+       if ((*m)->m_len < off + ICMP_MINLEN)
+               *m = m_pullup(*m, off + ICMP_MINLEN);
+       if (*m == NULL)
                return (ENOMEM);
-       switch (inner_proto) {
+       switch (proto) {
        case IPPROTO_TCP:
+               tcp = mtodo(*m, off);
+               *nat_proto = NAT_PROTO_TCP;
+               *port = ntohs(tcp->th_sport);
+               return (0);
        case IPPROTO_UDP:
-               /* Copy source port from the header */
-               *port = ntohs(*((uint16_t *)mtodo(*mp, off)));
-               *proto = inner_proto;
+               udp = mtodo(*m, off);
+               *nat_proto = NAT_PROTO_UDP;
+               *port = ntohs(udp->uh_sport);
                return (0);
        case IPPROTO_ICMP:
                /*
                 * We will translate only ICMP errors for our ICMP
                 * echo requests.
                 */
-               icmp = mtodo(*mp, off);
+               icmp = mtodo(*m, off);
                if (icmp->icmp_type != ICMP_ECHO)
                        return (EOPNOTSUPP);
-               *port = ntohs(icmp->icmp_id);
+               *port = ntohs(*((uint16_t *)(icmp + 1)));
                return (0);
        };
        return (EOPNOTSUPP);
 }
 
-static struct nat64lsn_state*
-nat64lsn_get_state4to6(struct nat64lsn_cfg *cfg, struct nat64lsn_alias *alias,
-    in_addr_t faddr, uint16_t port, uint8_t proto)
+static inline uint8_t
+convert_tcp_flags(uint8_t flags)
 {
-       struct nat64lsn_state *state;
-       struct nat64lsn_pg *pg;
-       int chunk_idx, pg_idx, state_idx;
+       uint8_t result;
 
-       NAT64LSN_EPOCH_ASSERT();
+       result = flags & (TH_FIN|TH_SYN);
+       result |= (flags & TH_RST) >> 2; /* Treat RST as FIN */
+       result |= (flags & TH_ACK) >> 2; /* Treat ACK as estab */
 
-       if (port < NAT64_MIN_PORT)
-               return (NULL);
-       /*
-        * Alias keeps 32 pgchunks for each protocol.
-        * Each pgchunk has 32 pointers to portgroup.
-        * Each portgroup has 64 states for ports.
-        */
-       port -= NAT64_MIN_PORT;
-       chunk_idx = port / 2048;
-
-       port -= chunk_idx * 2048;
-       pg_idx = port / 64;
-       state_idx = port % 64;
-
-       /*
-        * First check in proto_chunkmask that we have allocated PG chunk.
-        * Then check in proto_pgmask that we have valid PG pointer.
-        */
-       pg = NULL;
-       switch (proto) {
-       case IPPROTO_TCP:
-               if (ISSET32(alias->tcp_chunkmask, chunk_idx) &&
-                   ISSET32(alias->tcp_pgmask[chunk_idx], pg_idx)) {
-                       pg = alias->tcp[chunk_idx]->pgptr[pg_idx];
-                       break;
-               }
-               return (NULL);
-       case IPPROTO_UDP:
-               if (ISSET32(alias->udp_chunkmask, chunk_idx) &&
-                   ISSET32(alias->udp_pgmask[chunk_idx], pg_idx)) {
-                       pg = alias->udp[chunk_idx]->pgptr[pg_idx];
-                       break;
-               }
-               return (NULL);
-       case IPPROTO_ICMP:
-               if (ISSET32(alias->icmp_chunkmask, chunk_idx) &&
-                   ISSET32(alias->icmp_pgmask[chunk_idx], pg_idx)) {
-                       pg = alias->icmp[chunk_idx]->pgptr[pg_idx];
-                       break;
-               }

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to