Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 3 Apr 2017 08:50:55 +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-11@freebsd.org
Subject:   svn commit: r316446 - in stable/11: sbin/ipfw sys/conf sys/modules sys/modules/ipfw sys/modules/ipfw_nat64 sys/netinet sys/netinet6 sys/netpfil/ipfw sys/netpfil/ipfw/nat64
Message-ID:  <201704030850.v338othf078916@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: ae
Date: Mon Apr  3 08:50:54 2017
New Revision: 316446
URL: https://svnweb.freebsd.org/changeset/base/316446

Log:
  MFC r304041:
    Move logging via BPF support into separate file.
  
    * make interface cloner VNET-aware;
    * simplify cloner code and use if_clone_simple();
    * migrate LOGIF_LOCK() to rmlock;
    * add ipfw_bpf_mtap2() function to pass mbuf to BPF;
    * introduce new additional ipfwlog0 pseudo interface. It differs from
      ipfw0 by DLT type used in bpfattach. This interface is intended to
      used by ipfw modules to dump packets with additional info attached.
      Currently pflog format is used. ipfw_bpf_mtap2() function uses second
      argument to determine which interface use for dumping. If dlen is equal
      to ETHER_HDR_LEN it uses old ipfw0 interface, if dlen is equal to
      PFLOG_HDRLEN - ipfwlog0 will be used.
  
    Obtained from:	Yandex LLC
    Sponsored by:	Yandex LLC
  
  MFC r304043:
    Add three helper function to manage tables from external modules.
  
    ipfw_objhash_lookup_table_kidx does lookup kernel index of table;
    ipfw_ref_table/ipfw_unref_table takes and releases reference to table.
  
    Obtained from:	Yandex LLC
    Sponsored by:	Yandex LLC
  
  MFC r304046, 304108:
    Add ipfw_nat64 module that implements stateless and stateful NAT64.
  
    The module works together with ipfw(4) and implemented as its external
    action module.
  
    Stateless NAT64 registers external action with name nat64stl. This
    keyword should be used to create NAT64 instance and to address this
    instance in rules. Stateless NAT64 uses two lookup tables with mapped
    IPv4->IPv6 and IPv6->IPv4 addresses to perform translation.
  
    A configuration of instance should looks like this:
     1. Create lookup tables:
     # ipfw table T46 create type addr valtype ipv6
     # ipfw table T64 create type addr valtype ipv4
     2. Fill T46 and T64 tables.
     3. Add rule to allow neighbor solicitation and advertisement:
     # ipfw add allow icmp6 from any to any icmp6types 135,136
     4. Create NAT64 instance:
     # ipfw nat64stl NAT create table4 T46 table6 T64
     5. Add rules that matches the traffic:
     # ipfw add nat64stl NAT ip from any to table(T46)
     # ipfw add nat64stl NAT ip from table(T64) to 64:ff9b::/96
     6. Configure DNS64 for IPv6 clients and add route to 64:ff9b::/96
        via NAT64 host.
  
    Stateful NAT64 registers external action with name nat64lsn. The only
    one option required to create nat64lsn instance - prefix4. It defines
    the pool of IPv4 addresses used for translation.
  
    A configuration of instance should looks like this:
     1. Add rule to allow neighbor solicitation and advertisement:
     # ipfw add allow icmp6 from any to any icmp6types 135,136
     2. Create NAT64 instance:
     # ipfw nat64lsn NAT create prefix4 A.B.C.D/28
     3. Add rules that matches the traffic:
     # ipfw add nat64lsn NAT ip from any to A.B.C.D/28
     # ipfw add nat64lsn NAT ip6 from any to 64:ff9b::/96
     4. Configure DNS64 for IPv6 clients and add route to 64:ff9b::/96
        via NAT64 host.
  
    Obtained from:	Yandex LLC
    Relnotes:	yes
    Sponsored by:	Yandex LLC
    Differential Revision:	https://reviews.freebsd.org/D6434
  
  MFC r304048:
    Replace __noinline with special debug macro NAT64NOINLINE.
  
  MFC r304061:
    Use %ju to print unsigned 64-bit value.
  
  MFC r304076:
    Make statistics nat64lsn, nat64stl an nptv6 output netstat-like:
    "@value @description" and fix build due to -Wformat errors.
  
  MFC r304378 (by bz):
    Try to fix gcc compilation errors (which are right).
    nat64_getlasthdr() returns an int, which can be -1 in case of error,
    storing the result in an uint8_t and then comparing to < 0 is not
    helpful.  Do what is done in the rest of the code and make proto an
    int here as well.
  
  MFC r309187:
    Fix ICMPv6 Time Exceeded error message translation.
  
  MFC r314718:
    Use new ipfw_lookup_table() in the nat64 too.
  
  MFC r315204,315233:
    Use memset with structure size.

Added:
  stable/11/sbin/ipfw/nat64lsn.c
     - copied, changed from r304046, head/sbin/ipfw/nat64lsn.c
  stable/11/sbin/ipfw/nat64stl.c
     - copied, changed from r304046, head/sbin/ipfw/nat64stl.c
  stable/11/sys/modules/ipfw_nat64/
     - copied from r304046, head/sys/modules/ipfw_nat64/
  stable/11/sys/netinet6/ip_fw_nat64.h
     - copied unchanged from r304046, head/sys/netinet6/ip_fw_nat64.h
  stable/11/sys/netpfil/ipfw/ip_fw_bpf.c
     - copied unchanged from r304041, head/sys/netpfil/ipfw/ip_fw_bpf.c
  stable/11/sys/netpfil/ipfw/nat64/
     - copied from r304046, head/sys/netpfil/ipfw/nat64/
Modified:
  stable/11/sbin/ipfw/Makefile
  stable/11/sbin/ipfw/ipfw.8
  stable/11/sbin/ipfw/ipfw2.c
  stable/11/sbin/ipfw/ipfw2.h
  stable/11/sbin/ipfw/main.c
  stable/11/sbin/ipfw/tables.c
  stable/11/sys/conf/NOTES
  stable/11/sys/conf/files
  stable/11/sys/conf/options
  stable/11/sys/modules/Makefile
  stable/11/sys/modules/ipfw/Makefile
  stable/11/sys/netinet/ip_fw.h
  stable/11/sys/netpfil/ipfw/ip_fw2.c
  stable/11/sys/netpfil/ipfw/ip_fw_log.c
  stable/11/sys/netpfil/ipfw/ip_fw_private.h
  stable/11/sys/netpfil/ipfw/ip_fw_table.c
  stable/11/sys/netpfil/ipfw/nat64/nat64_translate.c
  stable/11/sys/netpfil/ipfw/nat64/nat64lsn.c
  stable/11/sys/netpfil/ipfw/nat64/nat64lsn_control.c
  stable/11/sys/netpfil/ipfw/nat64/nat64stl.c
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/sbin/ipfw/Makefile
==============================================================================
--- stable/11/sbin/ipfw/Makefile	Mon Apr  3 07:40:38 2017	(r316445)
+++ stable/11/sbin/ipfw/Makefile	Mon Apr  3 08:50:54 2017	(r316446)
@@ -5,7 +5,7 @@
 PACKAGE=ipfw
 PROG=	ipfw
 SRCS=	ipfw2.c dummynet.c ipv6.c main.c nat.c tables.c
-SRCS+=	nptv6.c
+SRCS+=	nat64lsn.c nat64stl.c nptv6.c
 WARNS?=	2
 
 .if ${MK_PF} != "no"

Modified: stable/11/sbin/ipfw/ipfw.8
==============================================================================
--- stable/11/sbin/ipfw/ipfw.8	Mon Apr  3 07:40:38 2017	(r316445)
+++ stable/11/sbin/ipfw/ipfw.8	Mon Apr  3 08:50:54 2017	(r316446)
@@ -113,6 +113,37 @@ in-kernel NAT.
 .Oc
 .Oc
 .Ar pathname
+.Ss STATEFUL IPv6/IPv4 NETWORK ADDRESS AND PROTOCOL TRANSLATION
+.Nm
+.Oo Cm set Ar N Oc Cm nat64lsn Ar name Cm create Ar create-options
+.Nm
+.Oo Cm set Ar N Oc Cm nat64lsn Ar name Cm config Ar config-options
+.Nm
+.Oo Cm set Ar N Oc Cm nat64lsn
+.Brq Ar name | all
+.Brq Cm list | show
+.Op Cm states
+.Nm
+.Oo Cm set Ar N Oc Cm nat64lsn
+.Brq Ar name | all
+.Cm destroy
+.Nm
+.Oo Cm set Ar N Oc Cm nat64lsn Ar name Cm stats Op Cm reset
+.Ss STATELESS IPv6/IPv4 NETWORK ADDRESS AND PROTOCOL TRANSLATION
+.Nm
+.Oo Cm set Ar N Oc Cm nat64stl Ar name Cm create Ar create-options
+.Nm
+.Oo Cm set Ar N Oc Cm nat64stl Ar name Cm config Ar config-options
+.Nm
+.Oo Cm set Ar N Oc Cm nat64stl
+.Brq Ar name | all
+.Brq Cm list | show
+.Nm
+.Oo Cm set Ar N Oc Cm nat64stl
+.Brq Ar name | all
+.Cm destroy
+.Nm
+.Oo Cm set Ar N Oc Cm nat64stl Ar name Cm stats Op Cm reset
 .Ss IPv6-to-IPv6 NETWORK PREFIX TRANSLATION
 .Nm
 .Oo Cm set Ar N Oc Cm nptv6 Ar name Cm create Ar create-options
@@ -837,6 +868,16 @@ nat instance
 see the
 .Sx NETWORK ADDRESS TRANSLATION (NAT)
 Section for further information.
+.It Cm nat64lsn Ar name
+Pass packet to a stateful NAT64 instance (for IPv6/IPv4 network address and
+protocol translation): see the
+.Sx IPv6/IPv4 NETWORK ADDRESS AND PROTOCOL TRANSLATION
+Section for further information.
+.It Cm nat64stl Ar name
+Pass packet to a stateless NAT64 instance (for IPv6/IPv4 network address and
+protocol translation): see the
+.Sx IPv6/IPv4 NETWORK ADDRESS AND PROTOCOL TRANSLATION
+Section for further information.
 .It Cm nptv6 Ar name
 Pass packet to a NPTv6 instance (for IPv6-to-IPv6 network prefix translation):
 see the
@@ -2944,9 +2985,189 @@ instances.
 See
 .Sx SYSCTL VARIABLES
 for more info.
+.Sh IPv6/IPv4 NETWORK ADDRESS AND PROTOCOL TRANSLATION
+.Nm
+supports in-kernel IPv6/IPv4 network address and protocol translation.
+Stateful NAT64 translation allows IPv6-only clients to contact IPv4 servers
+using unicast TCP, UDP or ICMP protocols.
+One or more IPv4 addresses assigned to a stateful NAT64 translator are shared
+among serveral IPv6-only clients.
+When stateful NAT64 is used in conjunction with DNS64, no changes are usually
+required in the IPv6 client or the IPv4 server.
+The kernel module
+.Cm ipfw_nat64
+should be loaded or kernel should have
+.Cm options IPFIREWALL_NAT64
+to be able use stateful NAT64 translator.
+.Pp
+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 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
+NAT64 translator follows RFC7915 when does ICMPv6/ICMP translation,
+unsupported message types will be silently dropped.
+IPv6 needs several ICMPv6 message types to be explicitly allowed for correct
+operation.
+Make sure that ND6 neighbor solicitation (ICMPv6 type 135) and neighbor
+advertisement (ICMPv6 type 136) messages will not be handled by translation
+rules.
+.Pp
+After translation NAT64 translator sends packets through corresponding netisr
+queue.
+Thus translator host should be configured as IPv4 and IPv6 router.
+.Pp
+Currently both stateful and stateless NAT64 translators use Well-Known IPv6
+Prefix
+.Ar 64:ff9b::/96
+to represent IPv4 addresses in the IPv6 address.
+Thus DNS64 service and routing should be configured to use Well-Known IPv6
+Prefix.
+.Pp
+The stateful NAT64 configuration command is the following:
+.Bd -ragged -offset indent
+.Bk -words
+.Cm nat64lsn
+.Ar name
+.Cm create
+.Ar create-options
+.Ek
+.Ed
+.Pp
+The following parameters can be configured:
+.Bl -tag -width indent
+.It Cm prefix4 Ar ipv4_prefix/mask
+The IPv4 prefix with mask defines the pool of IPv4 addresses used as
+source address after translation.
+Stateful NAT64 module translates IPv6 source address of client to one
+IPv4 address from this pool.
+Note that incoming IPv4 packets that don't have corresponding state entry
+in the states table will be dropped by translator.
+Make sure that translation rules handle packets, destined to configured prefix.
+.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.
+Default value is
+.Ar 3600 .
+.It Cm pg_del_age Ar seconds
+The number of seconds until a ports group with unused state entries will
+be released.
+Default value is
+.Ar 900 .
+.It Cm tcp_syn_age Ar seconds
+The number of seconds while a state entry for TCP connection with only SYN
+sent will be kept.
+If TCP connection establishing will not be finished,
+state entry will be deleted.
+Default value is
+.Ar 10 .
+.It Cm tcp_est_age Ar seconds
+The number of seconds while a state entry for established TCP connection
+will be kept.
+Default value is
+.Ar 7200 .
+.It Cm tcp_close_age Ar seconds
+The number of seconds while a state entry for closed TCP connection
+will be kept.
+Keeping state entries for closed connections is needed, because IPv4 servers
+typically keep closed connections in a TIME_WAIT state for a several minutes.
+Since translator's IPv4 addresses are shared among all IPv6 clients,
+new connections from the same addresses and ports may be rejected by server,
+because these connections are still in a TIME_WAIT state.
+Keeping them in translator's state table protects from such rejects.
+Default value is
+.Ar 180 .
+.It Cm udp_age Ar seconds
+The number of seconds while translator keeps state entry in a waiting for
+reply to the sent UDP datagram.
+Default value is
+.Ar 120 .
+.It Cm icmp_age Ar seconds
+The number of seconds while translator keeps state entry in a waiting for
+reply to the sent ICMP message.
+Default value is
+.Ar 60 .
+.It Cm log
+Turn on logging of all handled packets via BPF through
+.Ar ipfwlog0
+interface.
+.Ar ipfwlog0
+is a pseudo interface and can be created after a boot manually with
+.Cm ifconfig
+command.
+Note that it has different purpose than
+.Ar ipfw0
+interface.
+Translators sends to BPF an additional information with each packet.
+With
+.Cm tcpdump
+you are able to see each handled packet before and after translation.
+.It Cm -log
+Turn off logging of all handled packets via BPF.
+.El
+.Pp
+To inspect a states table of stateful NAT64 the following command can be used:
+.Bd -ragged -offset indent
+.Bk -words
+.Cm nat64lsn
+.Ar name
+.Cm show Cm states
+.Ek
+.Ed
+.Pp
+.Pp
+Stateless NAT64 translator doesn't use a states table for translation
+and converts IPv4 addresses to IPv6 and vice versa solely based on the
+mappings taken from configured lookup tables.
+Since a states table doesn't used by stateless translator,
+it can be configured to pass IPv4 clients to IPv6-only servers.
+.Pp
+The stateless NAT64 configuration command is the following:
+.Bd -ragged -offset indent
+.Bk -words
+.Cm nat64stl
+.Ar name
+.Cm create
+.Ar create-options
+.Ek
+.Ed
+.Pp
+The following parameters can be configured:
+.Bl -tag -width indent
+.It Cm table4 Ar table46
+The lookup table
+.Ar table46
+contains mapping how IPv4 addresses should be translated to IPv6 addresses.
+.It Cm table6 Ar table64
+The lookup table
+.Ar table64
+contains mapping how IPv6 addresses should be translated to IPv4 addresses.
+.It Cm log
+Turn on logging of all handled packets via BPF through
+.Ar ipfwlog0
+interface.
+.It Cm -log
+Turn off logging of all handled packets via BPF.
+.El
+.Pp
+Note that the behavior of stateless translator with respect to not matched
+packets differs from stateful translator.
+If corresponding addresses was not found in the lookup tables, the packet
+will not be dropped and the search continues.
 .Sh IPv6-to-IPv6 NETWORK PREFIX TRANSLATION (NPTv6)
 .Nm
-support in-kernel IPv6-to-IPv6 network prefix translation as described
+supports in-kernel IPv6-to-IPv6 network prefix translation as described
 in RFC6296.
 The kernel module
 .Cm ipfw_nptv6

Modified: stable/11/sbin/ipfw/ipfw2.c
==============================================================================
--- stable/11/sbin/ipfw/ipfw2.c	Mon Apr  3 07:40:38 2017	(r316445)
+++ stable/11/sbin/ipfw/ipfw2.c	Mon Apr  3 08:50:54 2017	(r316446)
@@ -235,6 +235,8 @@ static struct _s_x ether_types[] = {
 };
 
 static struct _s_x rule_eactions[] = {
+	{ "nat64lsn",		TOK_NAT64LSN },
+	{ "nat64stl",		TOK_NAT64STL },
 	{ "nptv6",		TOK_NPTV6 },
 	{ NULL, 0 }	/* terminator */
 };

Modified: stable/11/sbin/ipfw/ipfw2.h
==============================================================================
--- stable/11/sbin/ipfw/ipfw2.h	Mon Apr  3 07:40:38 2017	(r316445)
+++ stable/11/sbin/ipfw/ipfw2.h	Mon Apr  3 08:50:54 2017	(r316446)
@@ -254,7 +254,30 @@ enum tokens {
 	TOK_UNLOCK,
 	TOK_VLIST,
 	TOK_OLIST,
+
+	/* NAT64 tokens */
+	TOK_NAT64STL,
+	TOK_NAT64LSN,
 	TOK_STATS,
+	TOK_STATES,
+	TOK_CONFIG,
+	TOK_TABLE4,
+	TOK_TABLE6,
+	TOK_PREFIX4,
+	TOK_PREFIX6,
+	TOK_AGG_LEN,
+	TOK_AGG_COUNT,
+	TOK_MAX_PORTS,
+	TOK_JMAXLEN,
+	TOK_PORT_RANGE,
+	TOK_HOST_DEL_AGE,
+	TOK_PG_DEL_AGE,
+	TOK_TCP_SYN_AGE,
+	TOK_TCP_CLOSE_AGE,
+	TOK_TCP_EST_AGE,
+	TOK_UDP_AGE,
+	TOK_ICMP_AGE,
+	TOK_LOGOFF,
 
 	/* NPTv6 tokens */
 	TOK_NPTV6,
@@ -347,6 +370,8 @@ void ipfw_flush(int force);
 void ipfw_zero(int ac, char *av[], int optname);
 void ipfw_list(int ac, char *av[], int show_counters);
 void ipfw_internal_handler(int ac, char *av[]);
+void ipfw_nat64lsn_handler(int ac, char *av[]);
+void ipfw_nat64stl_handler(int ac, char *av[]);
 void ipfw_nptv6_handler(int ac, char *av[]);
 int ipfw_check_object_name(const char *name);
 
@@ -389,7 +414,10 @@ void fill_table(struct _ipfw_insn *cmd, 
 
 /* tables.c */
 struct _ipfw_obj_ctlv;
+struct _ipfw_obj_ntlv;
 int table_check_name(const char *tablename);
 void ipfw_list_ta(int ac, char *av[]);
 void ipfw_list_values(int ac, char *av[]);
+void table_fill_ntlv(struct _ipfw_obj_ntlv *ntlv, const char *name,
+    uint8_t set, uint16_t uidx);
 

Modified: stable/11/sbin/ipfw/main.c
==============================================================================
--- stable/11/sbin/ipfw/main.c	Mon Apr  3 07:40:38 2017	(r316445)
+++ stable/11/sbin/ipfw/main.c	Mon Apr  3 08:50:54 2017	(r316446)
@@ -425,6 +425,10 @@ ipfw_main(int oldac, char **oldav)
 	if (co.use_set || try_next) {
 		if (_substrcmp(*av, "delete") == 0)
 			ipfw_delete(av);
+		else if (!strncmp(*av, "nat64stl", strlen(*av)))
+			ipfw_nat64stl_handler(ac, av);
+		else if (!strncmp(*av, "nat64lsn", strlen(*av)))
+			ipfw_nat64lsn_handler(ac, av);
 		else if (!strncmp(*av, "nptv6", strlen(*av)))
 			ipfw_nptv6_handler(ac, av);
 		else if (_substrcmp(*av, "flush") == 0)

Copied and modified: stable/11/sbin/ipfw/nat64lsn.c (from r304046, head/sbin/ipfw/nat64lsn.c)
==============================================================================
--- head/sbin/ipfw/nat64lsn.c	Sat Aug 13 16:09:49 2016	(r304046, copy source)
+++ stable/11/sbin/ipfw/nat64lsn.c	Mon Apr  3 08:50:54 2017	(r316446)
@@ -37,6 +37,7 @@ __FBSDID("$FreeBSD$");
 #include <ctype.h>
 #include <err.h>
 #include <errno.h>
+#include <inttypes.h>
 #include <netdb.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -687,7 +688,6 @@ nat64lsn_get_stats(const char *name, uin
 	return (-1);
 }
 
-#define	_P_STAT(_s, _f)	printf("%8s:\t%lu\n", #_f, _s._f)
 static void
 nat64lsn_stats(const char *name, uint8_t set)
 {
@@ -696,34 +696,61 @@ nat64lsn_stats(const char *name, uint8_t
 	if (nat64lsn_get_stats(name, set, &stats) != 0)
 		err(EX_OSERR, "Error retrieving stats");
 
-	_P_STAT(stats, opcnt64);
-	_P_STAT(stats, opcnt46);
-	_P_STAT(stats, ofrags);
-	_P_STAT(stats, ifrags);
-	_P_STAT(stats, oerrors);
-	_P_STAT(stats, noroute4);
-	_P_STAT(stats, noroute6);
-	_P_STAT(stats, noproto);
-	_P_STAT(stats, nomem);
-	_P_STAT(stats, dropped);
-
-	_P_STAT(stats, hostcount);
-	_P_STAT(stats, tcpchunks);
-	_P_STAT(stats, udpchunks);
-	_P_STAT(stats, icmpchunks);
-	_P_STAT(stats, jcalls);
-	_P_STAT(stats, jrequests);
-	_P_STAT(stats, jhostsreq);
-	_P_STAT(stats, jportreq);
-	_P_STAT(stats, jhostfails);
-	_P_STAT(stats, jportfails);
-	_P_STAT(stats, jreinjected);
-	_P_STAT(stats, jmaxlen);
-	_P_STAT(stats, jnomem);
-	_P_STAT(stats, screated);
-	_P_STAT(stats, sdeleted);
-	_P_STAT(stats, spgcreated);
-	_P_STAT(stats, spgdeleted);
+	if (co.use_set != 0 || set != 0)
+		printf("set %u ", set);
+	printf("nat64lsn %s\n", name);
+	printf("\t%ju packets translated from IPv6 to IPv4\n",
+	    (uintmax_t)stats.opcnt64);
+	printf("\t%ju packets translated from IPv4 to IPv6\n",
+	    (uintmax_t)stats.opcnt46);
+	printf("\t%ju IPv6 fragments created\n",
+	    (uintmax_t)stats.ofrags);
+	printf("\t%ju IPv4 fragments received\n",
+	    (uintmax_t)stats.ifrags);
+	printf("\t%ju output packets dropped due to no bufs, etc.\n",
+	    (uintmax_t)stats.oerrors);
+	printf("\t%ju output packets discarded due to no IPv4 route\n",
+	    (uintmax_t)stats.noroute4);
+	printf("\t%ju output packets discarded due to no IPv6 route\n",
+	    (uintmax_t)stats.noroute6);
+	printf("\t%ju packets discarded due to unsupported protocol\n",
+	    (uintmax_t)stats.noproto);
+	printf("\t%ju packets discarded due to memory allocation problems\n",
+	    (uintmax_t)stats.nomem);
+	printf("\t%ju packets discarded due to some errors\n",
+	    (uintmax_t)stats.dropped);
+	printf("\t%ju packets not matched with IPv4 prefix\n",
+	    (uintmax_t)stats.nomatch4);
+
+	printf("\t%ju mbufs queued for post processing\n",
+	    (uintmax_t)stats.jreinjected);
+	printf("\t%ju times the job queue was processed\n",
+	    (uintmax_t)stats.jcalls);
+	printf("\t%ju job requests queued\n",
+	    (uintmax_t)stats.jrequests);
+	printf("\t%ju job requests queue limit reached\n",
+	    (uintmax_t)stats.jmaxlen);
+	printf("\t%ju job requests failed due to memory allocation problems\n",
+	    (uintmax_t)stats.jnomem);
+
+	printf("\t%ju hosts allocated\n", (uintmax_t)stats.hostcount);
+	printf("\t%ju hosts requested\n", (uintmax_t)stats.jhostsreq);
+	printf("\t%ju host requests failed\n", (uintmax_t)stats.jhostfails);
+
+	printf("\t%ju portgroups requested\n", (uintmax_t)stats.jportreq);
+	printf("\t%ju portgroups allocated\n", (uintmax_t)stats.spgcreated);
+	printf("\t%ju portgroups deleted\n", (uintmax_t)stats.spgdeleted);
+	printf("\t%ju portgroup requests failed\n",
+	    (uintmax_t)stats.jportfails);
+	printf("\t%ju portgroups allocated for TCP\n",
+	    (uintmax_t)stats.tcpchunks);
+	printf("\t%ju portgroups allocated for UDP\n",
+	    (uintmax_t)stats.udpchunks);
+	printf("\t%ju portgroups allocated for ICMP\n",
+	    (uintmax_t)stats.icmpchunks);
+
+	printf("\t%ju states created\n", (uintmax_t)stats.screated);
+	printf("\t%ju states deleted\n", (uintmax_t)stats.sdeleted);
 }
 
 static int

Copied and modified: stable/11/sbin/ipfw/nat64stl.c (from r304046, head/sbin/ipfw/nat64stl.c)
==============================================================================
--- head/sbin/ipfw/nat64stl.c	Sat Aug 13 16:09:49 2016	(r304046, copy source)
+++ stable/11/sbin/ipfw/nat64stl.c	Mon Apr  3 08:50:54 2017	(r316446)
@@ -36,6 +36,7 @@ __FBSDID("$FreeBSD$");
 #include <ctype.h>
 #include <err.h>
 #include <errno.h>
+#include <inttypes.h>
 #include <netdb.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -386,7 +387,6 @@ nat64stl_get_stats(const char *name, uin
 	return (-1);
 }
 
-#define	_P_STAT(_s, _f)	printf("%8s:\t%lu\n", #_f, _s._f)
 static void
 nat64stl_stats(const char *name, uint8_t set)
 {
@@ -395,16 +395,30 @@ nat64stl_stats(const char *name, uint8_t
 	if (nat64stl_get_stats(name, set, &stats) != 0)
 		err(EX_OSERR, "Error retrieving stats");
 
-	_P_STAT(stats, opcnt64);
-	_P_STAT(stats, opcnt46);
-	_P_STAT(stats, ofrags);
-	_P_STAT(stats, ifrags);
-	_P_STAT(stats, oerrors);
-	_P_STAT(stats, noroute4);
-	_P_STAT(stats, noroute6);
-	_P_STAT(stats, noproto);
-	_P_STAT(stats, nomem);
-	_P_STAT(stats, dropped);
+	if (co.use_set != 0 || set != 0)
+		printf("set %u ", set);
+	printf("nat64stl %s\n", name);
+
+	printf("\t%ju packets translated from IPv6 to IPv4\n",
+	    (uintmax_t)stats.opcnt64);
+	printf("\t%ju packets translated from IPv4 to IPv6\n",
+	    (uintmax_t)stats.opcnt46);
+	printf("\t%ju IPv6 fragments created\n",
+	    (uintmax_t)stats.ofrags);
+	printf("\t%ju IPv4 fragments received\n",
+	    (uintmax_t)stats.ifrags);
+	printf("\t%ju output packets dropped due to no bufs, etc.\n",
+	    (uintmax_t)stats.oerrors);
+	printf("\t%ju output packets discarded due to no IPv4 route\n",
+	    (uintmax_t)stats.noroute4);
+	printf("\t%ju output packets discarded due to no IPv6 route\n",
+	    (uintmax_t)stats.noroute6);
+	printf("\t%ju packets discarded due to unsupported protocol\n",
+	    (uintmax_t)stats.noproto);
+	printf("\t%ju packets discarded due to memory allocation problems\n",
+	    (uintmax_t)stats.nomem);
+	printf("\t%ju packets discarded due to some errors\n",
+	    (uintmax_t)stats.dropped);
 }
 
 /*

Modified: stable/11/sbin/ipfw/tables.c
==============================================================================
--- stable/11/sbin/ipfw/tables.c	Mon Apr  3 07:40:38 2017	(r316445)
+++ stable/11/sbin/ipfw/tables.c	Mon Apr  3 08:50:54 2017	(r316446)
@@ -53,8 +53,6 @@ static void table_lock(ipfw_obj_header *
 static int table_swap(ipfw_obj_header *oh, char *second);
 static int table_get_info(ipfw_obj_header *oh, ipfw_xtable_info *i);
 static int table_show_info(ipfw_xtable_info *i, void *arg);
-static void table_fill_ntlv(ipfw_obj_ntlv *ntlv, const char *name,
-    uint32_t set, uint16_t uidx);
 
 static int table_flush_one(ipfw_xtable_info *i, void *arg);
 static int table_show_one(ipfw_xtable_info *i, void *arg);
@@ -155,7 +153,7 @@ ipfw_table_handler(int ac, char *av[])
 	ipfw_xtable_info i;
 	ipfw_obj_header oh;
 	char *tablename;
-	uint32_t set;
+	uint8_t set;
 	void *arg;
 
 	memset(&oh, 0, sizeof(oh));
@@ -292,8 +290,8 @@ ipfw_table_handler(int ac, char *av[])
 	}
 }
 
-static void
-table_fill_ntlv(ipfw_obj_ntlv *ntlv, const char *name, uint32_t set,
+void
+table_fill_ntlv(ipfw_obj_ntlv *ntlv, const char *name, uint8_t set,
     uint16_t uidx)
 {
 

Modified: stable/11/sys/conf/NOTES
==============================================================================
--- stable/11/sys/conf/NOTES	Mon Apr  3 07:40:38 2017	(r316445)
+++ stable/11/sys/conf/NOTES	Mon Apr  3 08:50:54 2017	(r316446)
@@ -953,6 +953,8 @@ device		lagg
 # IPFIREWALL_NAT adds support for in kernel nat in ipfw, and it requires
 # LIBALIAS.
 #
+# IPFIREWALL_NAT64 adds support for in kernel NAT64 in ipfw.
+#
 # IPFIREWALL_NPTV6 adds support for in kernel NPTv6 in ipfw.
 #
 # IPSTEALTH enables code to support stealth forwarding (i.e., forwarding
@@ -976,6 +978,7 @@ options 	IPFIREWALL_VERBOSE	#enable logg
 options 	IPFIREWALL_VERBOSE_LIMIT=100	#limit verbosity
 options 	IPFIREWALL_DEFAULT_TO_ACCEPT	#allow everything by default
 options 	IPFIREWALL_NAT		#ipfw kernel nat support
+options 	IPFIREWALL_NAT64	#ipfw kernel NAT64 support
 options 	IPFIREWALL_NPTV6	#ipfw kernel IPv6 NPT support
 options 	IPDIVERT		#divert sockets
 options 	IPFILTER		#ipfilter support

Modified: stable/11/sys/conf/files
==============================================================================
--- stable/11/sys/conf/files	Mon Apr  3 07:40:38 2017	(r316445)
+++ stable/11/sys/conf/files	Mon Apr  3 08:50:54 2017	(r316446)
@@ -3932,6 +3932,7 @@ netpfil/ipfw/ip_dummynet.c	optional inet
 netpfil/ipfw/ip_dn_io.c		optional inet dummynet
 netpfil/ipfw/ip_dn_glue.c	optional inet dummynet
 netpfil/ipfw/ip_fw2.c		optional inet ipfirewall
+netpfil/ipfw/ip_fw_bpf.c	optional inet ipfirewall
 netpfil/ipfw/ip_fw_dynamic.c	optional inet ipfirewall
 netpfil/ipfw/ip_fw_eaction.c	optional inet ipfirewall
 netpfil/ipfw/ip_fw_log.c	optional inet ipfirewall
@@ -3942,6 +3943,18 @@ netpfil/ipfw/ip_fw_table_algo.c	optional
 netpfil/ipfw/ip_fw_table_value.c	optional inet ipfirewall
 netpfil/ipfw/ip_fw_iface.c	optional inet ipfirewall
 netpfil/ipfw/ip_fw_nat.c	optional inet ipfirewall_nat
+netpfil/ipfw/nat64/ip_fw_nat64.c	optional inet inet6 ipfirewall \
+	ipfirewall_nat64
+netpfil/ipfw/nat64/nat64lsn.c	optional inet inet6 ipfirewall \
+	ipfirewall_nat64
+netpfil/ipfw/nat64/nat64lsn_control.c	optional inet inet6 ipfirewall \
+	ipfirewall_nat64
+netpfil/ipfw/nat64/nat64stl.c	optional inet inet6 ipfirewall \
+	ipfirewall_nat64
+netpfil/ipfw/nat64/nat64stl_control.c	optional inet inet6 ipfirewall \
+	ipfirewall_nat64
+netpfil/ipfw/nat64/nat64_translate.c	optional inet inet6 ipfirewall \
+	ipfirewall_nat64
 netpfil/ipfw/nptv6/ip_fw_nptv6.c	optional inet inet6 ipfirewall \
 	ipfirewall_nptv6
 netpfil/ipfw/nptv6/nptv6.c	optional inet inet6 ipfirewall \

Modified: stable/11/sys/conf/options
==============================================================================
--- stable/11/sys/conf/options	Mon Apr  3 07:40:38 2017	(r316445)
+++ stable/11/sys/conf/options	Mon Apr  3 08:50:54 2017	(r316446)
@@ -419,6 +419,8 @@ IPFILTER_LOOKUP		opt_ipfilter.h
 IPFIREWALL		opt_ipfw.h
 IPFIREWALL_DEFAULT_TO_ACCEPT	opt_ipfw.h
 IPFIREWALL_NAT		opt_ipfw.h
+IPFIREWALL_NAT64	opt_ipfw.h
+IPFIREWALL_NAT64_DIRECT_OUTPUT	opt_ipfw.h
 IPFIREWALL_NPTV6	opt_ipfw.h
 IPFIREWALL_VERBOSE	opt_ipfw.h
 IPFIREWALL_VERBOSE_LIMIT	opt_ipfw.h

Modified: stable/11/sys/modules/Makefile
==============================================================================
--- stable/11/sys/modules/Makefile	Mon Apr  3 07:40:38 2017	(r316445)
+++ stable/11/sys/modules/Makefile	Mon Apr  3 08:50:54 2017	(r316446)
@@ -173,6 +173,7 @@ SUBDIR=	\
 	${_ipfilter} \
 	${_ipfw} \
 	ipfw_nat \
+	${_ipfw_nat64} \
 	${_ipfw_nptv6} \
 	${_ipmi} \
 	ip6_mroute_mod \
@@ -473,6 +474,9 @@ _if_stf=	if_stf
 _if_me=		if_me
 _ipdivert=	ipdivert
 _ipfw=		ipfw
+.if ${MK_INET6_SUPPORT} != "no" || defined(ALL_MODULES)
+_ipfw_nat64=	ipfw_nat64
+.endif
 .endif
 
 .if ${MK_INET6_SUPPORT} != "no" || defined(ALL_MODULES)

Modified: stable/11/sys/modules/ipfw/Makefile
==============================================================================
--- stable/11/sys/modules/ipfw/Makefile	Mon Apr  3 07:40:38 2017	(r316445)
+++ stable/11/sys/modules/ipfw/Makefile	Mon Apr  3 08:50:54 2017	(r316446)
@@ -3,7 +3,7 @@
 .PATH: ${.CURDIR}/../../netpfil/ipfw
 
 KMOD=	ipfw
-SRCS=	ip_fw2.c ip_fw_pfil.c
+SRCS=	ip_fw2.c ip_fw_pfil.c ip_fw_bpf.c
 SRCS+=	ip_fw_dynamic.c ip_fw_log.c ip_fw_eaction.c
 SRCS+=	ip_fw_sockopt.c ip_fw_table.c ip_fw_table_algo.c ip_fw_iface.c
 SRCS+=	ip_fw_table_value.c

Modified: stable/11/sys/netinet/ip_fw.h
==============================================================================
--- stable/11/sys/netinet/ip_fw.h	Mon Apr  3 07:40:38 2017	(r316445)
+++ stable/11/sys/netinet/ip_fw.h	Mon Apr  3 08:50:54 2017	(r316446)
@@ -110,6 +110,21 @@ typedef struct _ip_fw3_opheader {
 #define	IP_FW_DUMP_SOPTCODES	116	/* Dump available sopts/versions */
 #define	IP_FW_DUMP_SRVOBJECTS	117	/* Dump existing named objects */
 
+#define	IP_FW_NAT64STL_CREATE	130	/* Create stateless NAT64 instance */
+#define	IP_FW_NAT64STL_DESTROY	131	/* Destroy stateless NAT64 instance */
+#define	IP_FW_NAT64STL_CONFIG	132	/* Modify stateless NAT64 instance */
+#define	IP_FW_NAT64STL_LIST	133	/* List stateless NAT64 instances */
+#define	IP_FW_NAT64STL_STATS	134	/* Get NAT64STL instance statistics */
+#define	IP_FW_NAT64STL_RESET_STATS 135	/* Reset NAT64STL instance statistics */
+
+#define	IP_FW_NAT64LSN_CREATE	140	/* Create stateful NAT64 instance */
+#define	IP_FW_NAT64LSN_DESTROY	141	/* Destroy stateful NAT64 instance */
+#define	IP_FW_NAT64LSN_CONFIG	142	/* Modify stateful NAT64 instance */
+#define	IP_FW_NAT64LSN_LIST	143	/* List stateful NAT64 instances */
+#define	IP_FW_NAT64LSN_STATS	144	/* Get NAT64LSN instance statistics */
+#define	IP_FW_NAT64LSN_LIST_STATES 145	/* Get stateful NAT64 states */
+#define	IP_FW_NAT64LSN_RESET_STATS 146	/* Reset NAT64LSN instance statistics */
+
 #define	IP_FW_NPTV6_CREATE	150	/* Create NPTv6 instance */
 #define	IP_FW_NPTV6_DESTROY	151	/* Destroy NPTv6 instance */
 #define	IP_FW_NPTV6_CONFIG	152	/* Modify NPTv6 instance */
@@ -793,11 +808,17 @@ typedef struct  _ipfw_obj_tlv {
 #define	IPFW_TLV_RANGE		9
 #define	IPFW_TLV_EACTION	10
 #define	IPFW_TLV_COUNTERS	11
+#define	IPFW_TLV_OBJDATA	12
 #define	IPFW_TLV_STATE_NAME	14
 
 #define	IPFW_TLV_EACTION_BASE	1000
 #define	IPFW_TLV_EACTION_NAME(arg)	(IPFW_TLV_EACTION_BASE + (arg))
 
+typedef struct _ipfw_obj_data {
+	ipfw_obj_tlv	head;
+	void		*data[0];
+} ipfw_obj_data;
+
 /* Object name TLV */
 typedef struct _ipfw_obj_ntlv {
 	ipfw_obj_tlv	head;		/* TLV header			*/

Copied: stable/11/sys/netinet6/ip_fw_nat64.h (from r304046, head/sys/netinet6/ip_fw_nat64.h)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ stable/11/sys/netinet6/ip_fw_nat64.h	Mon Apr  3 08:50:54 2017	(r316446, copy of r304046, head/sys/netinet6/ip_fw_nat64.h)
@@ -0,0 +1,154 @@
+/*-
+ * Copyright (c) 2015 Yandex LLC
+ * Copyright (c) 2015 Alexander V. Chernikov <melifaro@FreeBSD.org>
+ * Copyright (c) 2016 Andrey V. Elsukov <ae@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef	_NETINET6_IP_FW_NAT64_H_
+#define	_NETINET6_IP_FW_NAT64_H_
+
+struct ipfw_nat64stl_stats {
+	uint64_t	opcnt64;	/* 6to4 of packets translated */
+	uint64_t	opcnt46;	/* 4to6 of packets translated */
+	uint64_t	ofrags;		/* number of fragments generated */
+	uint64_t	ifrags;		/* number of fragments received */
+	uint64_t	oerrors;	/* number of output errors */
+	uint64_t	noroute4;
+	uint64_t	noroute6;
+	uint64_t	noproto;	/* Protocol not supported */
+	uint64_t	nomem;		/* mbuf allocation filed */
+	uint64_t	dropped;	/* dropped due to some errors */
+};
+
+struct ipfw_nat64lsn_stats {
+	uint64_t	opcnt64;	/* 6to4 of packets translated */
+	uint64_t	opcnt46;	/* 4to6 of packets translated */
+	uint64_t	ofrags;		/* number of fragments generated */
+	uint64_t	ifrags;		/* number of fragments received */
+	uint64_t	oerrors;	/* number of output errors */
+	uint64_t	noroute4;
+	uint64_t	noroute6;
+	uint64_t	noproto;	/* Protocol not supported */
+	uint64_t	nomem;		/* mbuf allocation filed */
+	uint64_t	dropped;	/* dropped due to some errors */
+
+	uint64_t	nomatch4;	/* No addr/port match */
+	uint64_t	jcalls;		/* Number of job handler calls */
+	uint64_t	jrequests;	/* Number of job requests */
+	uint64_t	jhostsreq;	/* Number of job host requests */
+	uint64_t	jportreq;	/* Number of portgroup requests */
+	uint64_t	jhostfails;	/* Number of failed host allocs */
+	uint64_t	jportfails;	/* Number of failed portgroup allocs */
+	uint64_t	jreinjected;	/* Number of packets reinjected to q */
+	uint64_t	jmaxlen;	/* Max queue length reached */
+	uint64_t	jnomem;		/* No memory to alloc queue item */
+
+	uint64_t	screated;	/* Number of states created */
+	uint64_t	sdeleted;	/* Number of states deleted */
+	uint64_t	spgcreated;	/* Number of portgroups created */
+	uint64_t	spgdeleted;	/* Number of portgroups deleted */
+	uint64_t	hostcount;	/* Number of hosts  */
+	uint64_t	tcpchunks;	/* Number of TCP chunks */
+	uint64_t	udpchunks;	/* Number of UDP chunks */
+	uint64_t	icmpchunks;	/* Number of ICMP chunks */
+
+	uint64_t	_reserved[4];
+};
+
+#define	NAT64_LOG	0x0001		/* Enable logging via BPF */
+
+typedef struct _ipfw_nat64stl_cfg {
+	char		name[64];	/* NAT name			*/
+	ipfw_obj_ntlv	ntlv6;		/* object name tlv		*/
+	ipfw_obj_ntlv	ntlv4;		/* object name tlv		*/
+	struct in6_addr	prefix6;	/* NAT64 prefix */
+	uint8_t		plen6;		/* Prefix length */
+	uint8_t		set;		/* Named instance set [0..31] */
+	uint8_t		spare[2];
+	uint32_t	flags;
+} ipfw_nat64stl_cfg;
+
+/*
+ * NAT64LSN default configuration values
+ */
+#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 */
+#define	NAT64LSN_TCP_FIN_AGE	180	/* State's TTL after FIN/RST received */
+#define	NAT64LSN_UDP_AGE	120	/* TTL for UDP states */
+#define	NAT64LSN_ICMP_AGE	60	/* TTL for ICMP states */
+#define	NAT64LSN_HOST_AGE	3600	/* TTL for stale host entry */
+#define	NAT64LSN_PG_AGE		900	/* TTL for stale ports groups */
+
+typedef struct _ipfw_nat64lsn_cfg {
+	char		name[64];	/* NAT name			*/
+	uint32_t	flags;
+	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;	/* 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 */
+	uint16_t	st_close_ttl;	/* TCP fin expire */
+	uint16_t	st_estab_ttl;	/* TCP established expire */
+	uint16_t	st_udp_ttl;	/* UDP expire */
+	uint16_t	st_icmp_ttl;	/* ICMP expire */
+	uint8_t		set;		/* Named instance set [0..31] */
+	uint8_t		spare;
+} ipfw_nat64lsn_cfg;
+
+typedef struct _ipfw_nat64lsn_state {
+	struct in_addr	daddr;		/* Remote IPv4 address */
+	uint16_t	dport;		/* Remote destination port */
+	uint16_t	aport;		/* Local alias port */
+	uint16_t	sport;		/* Source port */
+	uint8_t		flags;		/* State flags */
+	uint8_t		spare[3];
+	uint16_t	idle;		/* Last used time */
+} ipfw_nat64lsn_state;
+
+typedef struct _ipfw_nat64lsn_stg {
+	uint64_t	next_idx;	/* next state index */
+	struct in_addr	alias4;		/* IPv4 alias address */
+	uint8_t		proto;		/* protocol */
+	uint8_t		flags;
+	uint16_t	spare;
+	struct in6_addr	host6;		/* Bound IPv6 host */
+	uint32_t	count;		/* Number of states */
+	uint32_t	spare2;
+} ipfw_nat64lsn_stg;
+
+#endif /* _NETINET6_IP_FW_NAT64_H_ */
+

Modified: stable/11/sys/netpfil/ipfw/ip_fw2.c
==============================================================================
--- stable/11/sys/netpfil/ipfw/ip_fw2.c	Mon Apr  3 07:40:38 2017	(r316445)
+++ stable/11/sys/netpfil/ipfw/ip_fw2.c	Mon Apr  3 08:50:54 2017	(r316446)
@@ -2846,6 +2846,7 @@ vnet_ipfw_init(const void *unused)
 #ifdef LINEAR_SKIPTO
 	ipfw_init_skipto_cache(chain);
 #endif
+	ipfw_bpf_init(first);
 
 	/* First set up some values that are compile time options */
 	V_ipfw_vnet_ready = 1;		/* Open for business */
@@ -2864,7 +2865,6 @@ vnet_ipfw_init(const void *unused)
 	 * is checked on each packet because there are no pfil hooks.
 	 */
 	V_ip_fw_ctl_ptr = ipfw_ctl3;
-	ipfw_log_bpf(1); /* init */
 	error = ipfw_attach_hooks(1);
 	return (error);
 }
@@ -2888,8 +2888,6 @@ vnet_ipfw_uninit(const void *unused)
 	(void)ipfw_attach_hooks(0 /* detach */);
 	V_ip_fw_ctl_ptr = NULL;
 
-	ipfw_log_bpf(0); /* uninit */
-
 	last = IS_DEFAULT_VNET(curvnet) ? 1 : 0;
 
 	IPFW_UH_WLOCK(chain);
@@ -2918,6 +2916,7 @@ vnet_ipfw_uninit(const void *unused)
 	IPFW_LOCK_DESTROY(chain);
 	ipfw_dyn_uninit(1);	/* free the remaining parts */
 	ipfw_destroy_counters();
+	ipfw_bpf_uninit(last);
 	return (0);
 }
 

Copied: stable/11/sys/netpfil/ipfw/ip_fw_bpf.c (from r304041, head/sys/netpfil/ipfw/ip_fw_bpf.c)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ stable/11/sys/netpfil/ipfw/ip_fw_bpf.c	Mon Apr  3 08:50:54 2017	(r316446, copy of r304041, head/sys/netpfil/ipfw/ip_fw_bpf.c)
@@ -0,0 +1,209 @@
+/*-
+ * Copyright (c) 2016 Yandex LLC
+ * Copyright (c) 2016 Andrey V. Elsukov <ae@FreeBSD.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/mbuf.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/rmlock.h>
+#include <sys/socket.h>
+#include <net/ethernet.h>
+#include <net/if.h>
+#include <net/if_pflog.h>
+#include <net/if_var.h>
+#include <net/if_clone.h>
+#include <net/if_types.h>
+#include <net/vnet.h>
+#include <net/bpf.h>
+
+#include <netinet/in.h>
+#include <netinet/ip_fw.h>
+#include <netinet/ip_var.h>
+#include <netpfil/ipfw/ip_fw_private.h>
+
+static VNET_DEFINE(struct ifnet *, log_if);
+static VNET_DEFINE(struct ifnet *, pflog_if);
+static VNET_DEFINE(struct if_clone *, ipfw_cloner);
+static VNET_DEFINE(struct if_clone *, ipfwlog_cloner);
+#define	V_ipfw_cloner		VNET(ipfw_cloner)
+#define	V_ipfwlog_cloner	VNET(ipfwlog_cloner)
+#define	V_log_if		VNET(log_if)
+#define	V_pflog_if		VNET(pflog_if)
+
+static struct rmlock log_if_lock;
+#define	LOGIF_LOCK_INIT(x)	rm_init(&log_if_lock, "ipfw log_if lock")
+#define	LOGIF_LOCK_DESTROY(x)	rm_destroy(&log_if_lock)
+#define	LOGIF_RLOCK_TRACKER	struct rm_priotracker _log_tracker
+#define	LOGIF_RLOCK(x)		rm_rlock(&log_if_lock, &_log_tracker)
+#define	LOGIF_RUNLOCK(x)	rm_runlock(&log_if_lock, &_log_tracker)
+#define	LOGIF_WLOCK(x)		rm_wlock(&log_if_lock)
+#define	LOGIF_WUNLOCK(x)	rm_wunlock(&log_if_lock)
+
+static const char ipfwname[] = "ipfw";
+static const char ipfwlogname[] = "ipfwlog";
+
+static int
+ipfw_bpf_ioctl(struct ifnet *ifp, u_long cmd, caddr_t addr)
+{
+
+	return (EINVAL);
+}
+
+static int
+ipfw_bpf_output(struct ifnet *ifp, struct mbuf *m,
+	const struct sockaddr *dst, struct route *ro)
+{
+
+	if (m != NULL)
+		FREE_PKT(m);
+	return (0);
+}
+
+static void
+ipfw_clone_destroy(struct ifnet *ifp)
+{
+
+	LOGIF_WLOCK();
+	if (ifp->if_hdrlen == ETHER_HDR_LEN)
+		V_log_if = NULL;
+	else
+		V_pflog_if = NULL;
+	LOGIF_WUNLOCK();
+
+	bpfdetach(ifp);
+	if_detach(ifp);
+	if_free(ifp);
+}
+
+static int
+ipfw_clone_create(struct if_clone *ifc, int unit, caddr_t params)
+{
+	struct ifnet *ifp;
+
+	ifp = if_alloc(IFT_PFLOG);
+	if (ifp == NULL)
+		return (ENOSPC);
+	if_initname(ifp, ipfwname, unit);
+	ifp->if_flags = IFF_UP | IFF_SIMPLEX | IFF_MULTICAST;
+	ifp->if_mtu = 65536;
+	ifp->if_ioctl = ipfw_bpf_ioctl;
+	ifp->if_output = ipfw_bpf_output;
+	ifp->if_hdrlen = ETHER_HDR_LEN;
+	if_attach(ifp);
+	bpfattach(ifp, DLT_EN10MB, ETHER_HDR_LEN);
+	LOGIF_WLOCK();
+	if (V_log_if != NULL) {
+		LOGIF_WUNLOCK();
+		bpfdetach(ifp);
+		if_detach(ifp);
+		if_free(ifp);
+		return (EEXIST);
+	}
+	V_log_if = ifp;
+	LOGIF_WUNLOCK();
+	return (0);
+}
+
+static int
+ipfwlog_clone_create(struct if_clone *ifc, int unit, caddr_t params)
+{
+	struct ifnet *ifp;
+
+	ifp = if_alloc(IFT_PFLOG);

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201704030850.v338othf078916>