Author: ae
Date: Mon Apr  3 07:30:47 2017
New Revision: 316444
URL: https://svnweb.freebsd.org/changeset/base/316444

Log:
  MFC r303012:
    Add ipfw_nptv6 module that implements Network Prefix Translation for IPv6
    as defined in RFC 6296. The module works together with ipfw(4) and
    implemented as its external action module. When it is loaded, it registers
    as eaction and can be used in rules. The usage pattern is similar to
    ipfw_nat(4). All matched by rule traffic goes to the NPT module.
  
    Reviewed by:        hrs
    Obtained from:      Yandex LLC
    Relnotes:   yes
    Sponsored by:       Yandex LLC
    Differential Revision:      https://reviews.freebsd.org/D6420
  
  MFC r304049:
    Add `stats reset` command implementation to NPTv6 module
    to be able reset statistics counters.
  
    Obtained from:      Yandex LLC
    Sponsored by:       Yandex LLC
  
  MFC r304076:
    Make statistics nat64lsn, nat64stl an nptv6 output netstat-like:
    "@value @description" and fix build due to -Wformat errors.
  
  MFC r314507:
    Fix NPTv6 rule counters when one_pass is not enabled.
  
    Consider the rule matching when both @done and @retval values
    returned from ipfw_run_eaction() are zero. And modify ipfw_nptv6()
    to return IP_FW_DENY and @done=0 when addresses do not match.
  
    Obtained from:      Yandex LLC
    Sponsored by:       Yandex LLC

Added:
  stable/11/sbin/ipfw/nptv6.c
     - copied, changed from r303012, head/sbin/ipfw/nptv6.c
  stable/11/sys/modules/ipfw_nptv6/
     - copied from r303012, head/sys/modules/ipfw_nptv6/
  stable/11/sys/netinet6/ip_fw_nptv6.h
     - copied unchanged from r303012, head/sys/netinet6/ip_fw_nptv6.h
  stable/11/sys/netpfil/ipfw/nptv6/
     - copied from r303012, head/sys/netpfil/ipfw/nptv6/
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/sys/conf/NOTES
  stable/11/sys/conf/files
  stable/11/sys/conf/options
  stable/11/sys/modules/Makefile
  stable/11/sys/netinet/ip_fw.h
  stable/11/sys/netpfil/ipfw/ip_fw2.c
  stable/11/sys/netpfil/ipfw/nptv6/nptv6.c
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/sbin/ipfw/Makefile
==============================================================================
--- stable/11/sbin/ipfw/Makefile        Mon Apr  3 06:52:02 2017        
(r316443)
+++ stable/11/sbin/ipfw/Makefile        Mon Apr  3 07:30:47 2017        
(r316444)
@@ -5,6 +5,7 @@
 PACKAGE=ipfw
 PROG=  ipfw
 SRCS=  ipfw2.c dummynet.c ipv6.c main.c nat.c tables.c
+SRCS+= nptv6.c
 WARNS?=        2
 
 .if ${MK_PF} != "no"

Modified: stable/11/sbin/ipfw/ipfw.8
==============================================================================
--- stable/11/sbin/ipfw/ipfw.8  Mon Apr  3 06:52:02 2017        (r316443)
+++ stable/11/sbin/ipfw/ipfw.8  Mon Apr  3 07:30:47 2017        (r316444)
@@ -113,6 +113,19 @@ in-kernel NAT.
 .Oc
 .Oc
 .Ar pathname
+.Ss IPv6-to-IPv6 NETWORK PREFIX TRANSLATION
+.Nm
+.Oo Cm set Ar N Oc Cm nptv6 Ar name Cm create Ar create-options
+.Nm
+.Oo Cm set Ar N Oc Cm nptv6
+.Brq Ar name | all
+.Brq Cm list | show
+.Nm
+.Oo Cm set Ar N Oc Cm nptv6
+.Brq Ar name | all
+.Cm destroy
+.Nm
+.Oo Cm set Ar N Oc Cm nptv6 Ar name Cm stats Op Cm reset
 .Ss INTERNAL DIAGNOSTICS
 .Nm
 .Cm internal iflist
@@ -824,6 +837,11 @@ nat instance
 see the
 .Sx NETWORK ADDRESS TRANSLATION (NAT)
 Section for further information.
+.It Cm nptv6 Ar name
+Pass packet to a NPTv6 instance (for IPv6-to-IPv6 network prefix translation):
+see the
+.Sx IPv6-to-IPv6 NETWORK PREFIX TRANSLATION (NPTv6)
+Section for further information.
 .It Cm pipe Ar pipe_nr
 Pass packet to a
 .Nm dummynet
@@ -2908,6 +2926,47 @@ instances.
 See
 .Sx SYSCTL VARIABLES
 for more info.
+.Sh IPv6-to-IPv6 NETWORK PREFIX TRANSLATION (NPTv6)
+.Nm
+support in-kernel IPv6-to-IPv6 network prefix translation as described
+in RFC6296.
+The kernel module
+.Cm ipfw_nptv6
+should be loaded or kernel should has
+.Cm options IPFIREWALL_NPTV6
+to be able use NPTv6 translator.
+.Pp
+The NPTv6 configuration command is the following:
+.Bd -ragged -offset indent
+.Bk -words
+.Cm nptv6
+.Ar name
+.Cm create
+.Ar create-options
+.Ek
+.Ed
+.Pp
+The following parameters can be configured:
+.Bl -tag -width indent
+.It Cm int_prefix Ar ipv6_prefix
+IPv6 prefix used in internal network.
+NPTv6 module translates source address when it matches this prefix.
+.It Cm ext_prefix Ar ipv6_prefix
+IPv6 prefix used in external network.
+NPTv6 module translates destination address when it matches this prefix.
+.It Cm prefixlen Ar length
+The length of specified IPv6 prefixes. It must be in range from 8 to 64.
+.El
+.Pp
+Note that the prefix translation rules are silently ignored when IPv6 packet
+forwarding is disabled.
+To enable the packet forwarding, set the sysctl variable
+.Va net.inet6.ip6.forwarding
+to 1.
+.Pp
+To let the packet continue after being translated, set the sysctl variable
+.Va net.inet.ip.fw.one_pass
+to 0.
 .Sh LOADER TUNABLES
 Tunables can be set in
 .Xr loader 8

Modified: stable/11/sbin/ipfw/ipfw2.c
==============================================================================
--- stable/11/sbin/ipfw/ipfw2.c Mon Apr  3 06:52:02 2017        (r316443)
+++ stable/11/sbin/ipfw/ipfw2.c Mon Apr  3 07:30:47 2017        (r316444)
@@ -235,6 +235,7 @@ static struct _s_x ether_types[] = {
 };
 
 static struct _s_x rule_eactions[] = {
+       { "nptv6",              TOK_NPTV6 },
        { NULL, 0 }     /* terminator */
 };
 

Modified: stable/11/sbin/ipfw/ipfw2.h
==============================================================================
--- stable/11/sbin/ipfw/ipfw2.h Mon Apr  3 06:52:02 2017        (r316443)
+++ stable/11/sbin/ipfw/ipfw2.h Mon Apr  3 07:30:47 2017        (r316444)
@@ -254,6 +254,13 @@ enum tokens {
        TOK_UNLOCK,
        TOK_VLIST,
        TOK_OLIST,
+       TOK_STATS,
+
+       /* NPTv6 tokens */
+       TOK_NPTV6,
+       TOK_INTPREFIX,
+       TOK_EXTPREFIX,
+       TOK_PREFIXLEN,
 };
 
 /*
@@ -340,6 +347,7 @@ 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_nptv6_handler(int ac, char *av[]);
 int ipfw_check_object_name(const char *name);
 
 #ifdef PF

Modified: stable/11/sbin/ipfw/main.c
==============================================================================
--- stable/11/sbin/ipfw/main.c  Mon Apr  3 06:52:02 2017        (r316443)
+++ stable/11/sbin/ipfw/main.c  Mon Apr  3 07:30:47 2017        (r316444)
@@ -425,6 +425,8 @@ ipfw_main(int oldac, char **oldav)
        if (co.use_set || try_next) {
                if (_substrcmp(*av, "delete") == 0)
                        ipfw_delete(av);
+               else if (!strncmp(*av, "nptv6", strlen(*av)))
+                       ipfw_nptv6_handler(ac, av);
                else if (_substrcmp(*av, "flush") == 0)
                        ipfw_flush(co.do_force);
                else if (_substrcmp(*av, "zero") == 0)

Copied and modified: stable/11/sbin/ipfw/nptv6.c (from r303012, 
head/sbin/ipfw/nptv6.c)
==============================================================================
--- head/sbin/ipfw/nptv6.c      Mon Jul 18 19:46:31 2016        (r303012, copy 
source)
+++ stable/11/sbin/ipfw/nptv6.c Mon Apr  3 07:30:47 2017        (r316444)
@@ -56,6 +56,7 @@ static int nptv6_foreach(nptv6_cb_t *f, 
 static void nptv6_create(const char *name, uint8_t set, int ac, char **av);
 static void nptv6_destroy(const char *name, uint8_t set);
 static void nptv6_stats(const char *name, uint8_t set);
+static void nptv6_reset_stats(const char *name, uint8_t set);
 static int nptv6_show_cb(ipfw_nptv6_cfg *cfg, const char *name, uint8_t set);
 static int nptv6_destroy_cb(ipfw_nptv6_cfg *cfg, const char *name, uint8_t 
set);
 
@@ -68,10 +69,15 @@ static struct _s_x nptv6cmds[] = {
       { NULL, 0 }
 };
 
+static struct _s_x nptv6statscmds[] = {
+      { "reset",       TOK_RESET },
+      { NULL, 0 }
+};
+
 /*
  * This one handles all NPTv6-related commands
  *     ipfw [set N] nptv6 NAME {create | config} ...
- *     ipfw [set N] nptv6 NAME stats
+ *     ipfw [set N] nptv6 NAME stats [reset]
  *     ipfw [set N] nptv6 {NAME | all} destroy
  *     ipfw [set N] nptv6 {NAME | all} {list | show}
  */
@@ -119,7 +125,14 @@ ipfw_nptv6_handler(int ac, char *av[])
                        nptv6_destroy(name, set);
                break;
        case TOK_STATS:
-               nptv6_stats(name, set);
+               ac--; av++;
+               if (ac == 0) {
+                       nptv6_stats(name, set);
+                       break;
+               }
+               tcmd = get_token(nptv6statscmds, *av, "stats command");
+               if (tcmd == TOK_RESET)
+                       nptv6_reset_stats(name, set);
        }
 }
 
@@ -296,14 +309,32 @@ nptv6_stats(const char *name, uint8_t se
        if (nptv6_get_stats(name, set, &stats) != 0)
                err(EX_OSERR, "Error retrieving stats");
 
-       printf("Number of packets translated (internal to external): %ju\n",
+       if (co.use_set != 0 || set != 0)
+               printf("set %u ", set);
+       printf("nptv6 %s\n", name);
+       printf("\t%ju packets translated (internal to external)\n",
            (uintmax_t)stats.in2ex);
-       printf("Number of packets translated (external to internal): %ju\n",
+       printf("\t%ju packets translated (external to internal)\n",
            (uintmax_t)stats.ex2in);
-       printf("Number of packets dropped due to some error: %ju\n",
+       printf("\t%ju packets dropped due to some error\n",
            (uintmax_t)stats.dropped);
 }
 
+/*
+ * Reset NPTv6 instance statistics specified by @oh->ntlv.
+ * Request: [ ipfw_obj_header ]
+ */
+static void
+nptv6_reset_stats(const char *name, uint8_t set)
+{
+       ipfw_obj_header oh;
+
+       memset(&oh, 0, sizeof(oh));
+       nptv6_fill_ntlv(&oh.ntlv, name, set);
+       if (do_set3(IP_FW_NPTV6_RESET_STATS, &oh.opheader, sizeof(oh)) != 0)
+               err(EX_OSERR, "failed to reset stats for instance %s", name);
+}
+
 static int
 nptv6_show_cb(ipfw_nptv6_cfg *cfg, const char *name, uint8_t set)
 {

Modified: stable/11/sys/conf/NOTES
==============================================================================
--- stable/11/sys/conf/NOTES    Mon Apr  3 06:52:02 2017        (r316443)
+++ stable/11/sys/conf/NOTES    Mon Apr  3 07:30:47 2017        (r316444)
@@ -953,6 +953,8 @@ device              lagg
 # IPFIREWALL_NAT adds support for in kernel nat in ipfw, and it requires
 # LIBALIAS.
 #
+# IPFIREWALL_NPTV6 adds support for in kernel NPTv6 in ipfw.
+#
 # IPSTEALTH enables code to support stealth forwarding (i.e., forwarding
 # packets without touching the TTL).  This can be useful to hide firewalls
 # from traceroute and similar tools.
@@ -974,6 +976,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_NPTV6        #ipfw kernel IPv6 NPT support
 options        IPDIVERT                #divert sockets
 options        IPFILTER                #ipfilter support
 options        IPFILTER_LOG            #ipfilter logging

Modified: stable/11/sys/conf/files
==============================================================================
--- stable/11/sys/conf/files    Mon Apr  3 06:52:02 2017        (r316443)
+++ stable/11/sys/conf/files    Mon Apr  3 07:30:47 2017        (r316444)
@@ -3942,6 +3942,10 @@ 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/nptv6/ip_fw_nptv6.c       optional inet inet6 ipfirewall \
+       ipfirewall_nptv6
+netpfil/ipfw/nptv6/nptv6.c     optional inet inet6 ipfirewall \
+       ipfirewall_nptv6
 netpfil/pf/if_pflog.c          optional pflog pf inet
 netpfil/pf/if_pfsync.c         optional pfsync pf inet
 netpfil/pf/pf.c                        optional pf inet

Modified: stable/11/sys/conf/options
==============================================================================
--- stable/11/sys/conf/options  Mon Apr  3 06:52:02 2017        (r316443)
+++ stable/11/sys/conf/options  Mon Apr  3 07:30:47 2017        (r316444)
@@ -419,6 +419,7 @@ IPFILTER_LOOKUP             opt_ipfilter.h
 IPFIREWALL             opt_ipfw.h
 IPFIREWALL_DEFAULT_TO_ACCEPT   opt_ipfw.h
 IPFIREWALL_NAT         opt_ipfw.h
+IPFIREWALL_NPTV6       opt_ipfw.h
 IPFIREWALL_VERBOSE     opt_ipfw.h
 IPFIREWALL_VERBOSE_LIMIT       opt_ipfw.h
 IPSEC                  opt_ipsec.h

Modified: stable/11/sys/modules/Makefile
==============================================================================
--- stable/11/sys/modules/Makefile      Mon Apr  3 06:52:02 2017        
(r316443)
+++ stable/11/sys/modules/Makefile      Mon Apr  3 07:30:47 2017        
(r316444)
@@ -173,6 +173,7 @@ SUBDIR=     \
        ${_ipfilter} \
        ${_ipfw} \
        ipfw_nat \
+       ${_ipfw_nptv6} \
        ${_ipmi} \
        ip6_mroute_mod \
        ip_mroute_mod \
@@ -474,6 +475,10 @@ _ipdivert= ipdivert
 _ipfw=         ipfw
 .endif
 
+.if ${MK_INET6_SUPPORT} != "no" || defined(ALL_MODULES)
+_ipfw_nptv6=   ipfw_nptv6
+.endif
+
 .if ${MK_IPFILTER} != "no" || defined(ALL_MODULES)
 _ipfilter=     ipfilter
 .endif

Modified: stable/11/sys/netinet/ip_fw.h
==============================================================================
--- stable/11/sys/netinet/ip_fw.h       Mon Apr  3 06:52:02 2017        
(r316443)
+++ stable/11/sys/netinet/ip_fw.h       Mon Apr  3 07:30:47 2017        
(r316444)
@@ -110,6 +110,13 @@ 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_NPTV6_CREATE      150     /* Create NPTv6 instance */
+#define        IP_FW_NPTV6_DESTROY     151     /* Destroy NPTv6 instance */
+#define        IP_FW_NPTV6_CONFIG      152     /* Modify NPTv6 instance */
+#define        IP_FW_NPTV6_LIST        153     /* List NPTv6 instances */
+#define        IP_FW_NPTV6_STATS       154     /* Get NPTv6 instance 
statistics */
+#define        IP_FW_NPTV6_RESET_STATS 155     /* Reset NPTv6 instance 
statistics */
+
 /*
  * The kernel representation of ipfw rules is made of a list of
  * 'instructions' (for all practical purposes equivalent to BPF
@@ -785,6 +792,7 @@ typedef struct  _ipfw_obj_tlv {
 #define        IPFW_TLV_TBLENT_LIST    8
 #define        IPFW_TLV_RANGE          9
 #define        IPFW_TLV_EACTION        10
+#define        IPFW_TLV_COUNTERS       11
 #define        IPFW_TLV_STATE_NAME     14
 
 #define        IPFW_TLV_EACTION_BASE   1000

Copied: stable/11/sys/netinet6/ip_fw_nptv6.h (from r303012, 
head/sys/netinet6/ip_fw_nptv6.h)
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ stable/11/sys/netinet6/ip_fw_nptv6.h        Mon Apr  3 07:30:47 2017        
(r316444, copy of r303012, head/sys/netinet6/ip_fw_nptv6.h)
@@ -0,0 +1,51 @@
+/*-
+ * Copyright (c) 2016 Yandex LLC
+ * Copyright (c) 2016 Andrey V. Elsukov <a...@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_NPTV6_H_
+#define        _NETINET6_IP_FW_NPTV6_H_
+
+struct ipfw_nptv6_stats {
+       uint64_t        in2ex;          /* Int->Ext packets translated */
+       uint64_t        ex2in;          /* Ext->Int packets translated */
+       uint64_t        dropped;        /* dropped due to some errors */
+       uint64_t        reserved[5];
+};
+
+typedef struct _ipfw_nptv6_cfg {
+       char            name[64];       /* NPTv6 instance name */
+       struct in6_addr internal;       /* NPTv6 internal prefix */
+       struct in6_addr external;       /* NPTv6 external prefix */
+       uint8_t         plen;           /* Prefix length */
+       uint8_t         set;            /* Named instance set [0..31] */
+       uint8_t         spare[2];
+       uint32_t        flags;
+} ipfw_nptv6_cfg;
+
+#endif /* _NETINET6_IP_FW_NPTV6_H_ */
+

Modified: stable/11/sys/netpfil/ipfw/ip_fw2.c
==============================================================================
--- stable/11/sys/netpfil/ipfw/ip_fw2.c Mon Apr  3 06:52:02 2017        
(r316443)
+++ stable/11/sys/netpfil/ipfw/ip_fw2.c Mon Apr  3 07:30:47 2017        
(r316444)
@@ -2611,6 +2611,13 @@ do {                                                     
        \
                                l = 0; /* in any case exit inner loop */
                                retval = ipfw_run_eaction(chain, args,
                                    cmd, &done);
+                               /*
+                                * If both @retval and @done are zero,
+                                * consider this as rule matching and
+                                * update counters.
+                                */
+                               if (retval == 0 && done == 0)
+                                       IPFW_INC_RULE_COUNTER(f, pktlen);
                                break;
 
                        default:

Modified: stable/11/sys/netpfil/ipfw/nptv6/nptv6.c
==============================================================================
--- head/sys/netpfil/ipfw/nptv6/nptv6.c Mon Jul 18 19:46:31 2016        
(r303012)
+++ stable/11/sys/netpfil/ipfw/nptv6/nptv6.c    Mon Apr  3 07:30:47 2017        
(r316444)
@@ -352,24 +352,24 @@ ipfw_nptv6(struct ip_fw_chain *chain, st
        int ret;
 
        *done = 0; /* try next rule if not matched */
+       ret = IP_FW_DENY;
        icmd = cmd + 1;
        if (cmd->opcode != O_EXTERNAL_ACTION ||
            cmd->arg1 != V_nptv6_eid ||
            icmd->opcode != O_EXTERNAL_INSTANCE ||
            (cfg = NPTV6_LOOKUP(chain, icmd)) == NULL)
-               return (0);
+               return (ret);
        /*
         * We need act as router, so when forwarding is disabled -
         * do nothing.
         */
        if (V_ip6_forwarding == 0 || args->f_id.addr_type != 6)
-               return (0);
+               return (ret);
        /*
         * NOTE: we expect ipfw_chk() did m_pullup() up to upper level
         * protocol's headers. Also we skip some checks, that ip6_input(),
         * ip6_forward(), ip6_fastfwd() and ipfw_chk() already did.
         */
-       ret = IP_FW_DENY;
        ip6 = mtod(args->m, struct ip6_hdr *);
        NPTV6_IPDEBUG("eid %u, oid %u, %s -> %s %d",
            cmd->arg1, icmd->arg1,
@@ -384,15 +384,15 @@ ipfw_nptv6(struct ip_fw_chain *chain, st
                 */
                if (IN6_ARE_MASKED_ADDR_EQUAL(&ip6->ip6_dst,
                    &cfg->internal, &cfg->mask))
-                       return (0);
+                       return (ret);
                ret = nptv6_rewrite_internal(cfg, &args->m, 0);
        } else if (IN6_ARE_MASKED_ADDR_EQUAL(&ip6->ip6_dst,
            &cfg->external, &cfg->mask))
                ret = nptv6_rewrite_external(cfg, &args->m, 0);
        else
-               return (0);
+               return (ret);
        /*
-        * If address wasn't rewrited - free mbuf.
+        * If address wasn't rewrited - free mbuf and terminate the search.
         */
        if (ret != 0) {
                if (args->m != NULL) {
@@ -400,14 +400,16 @@ ipfw_nptv6(struct ip_fw_chain *chain, st
                        args->m = NULL; /* mark mbuf as consumed */
                }
                NPTV6STAT_INC(cfg, dropped);
-       }
-       /* Terminate the search if one_pass is set */
-       *done = V_fw_one_pass;
-       /* Update args->f_id when one_pass is off */
-       if (*done == 0 && ret == 0) {
-               ip6 = mtod(args->m, struct ip6_hdr *);
-               args->f_id.src_ip6 = ip6->ip6_src;
-               args->f_id.dst_ip6 = ip6->ip6_dst;
+               *done = 1;
+       } else {
+               /* Terminate the search if one_pass is set */
+               *done = V_fw_one_pass;
+               /* Update args->f_id when one_pass is off */
+               if (*done == 0) {
+                       ip6 = mtod(args->m, struct ip6_hdr *);
+                       args->f_id.src_ip6 = ip6->ip6_src;
+                       args->f_id.dst_ip6 = ip6->ip6_dst;
+               }
        }
        return (ret);
 }
@@ -700,6 +702,9 @@ nptv6_stats(struct ip_fw_chain *ch, ip_f
        oh = (ipfw_obj_header *)ipfw_get_sopt_header(sd, sz);
        if (oh == NULL)
                return (EINVAL);
+       if (ipfw_check_object_name_generic(oh->ntlv.name) != 0 ||
+           oh->ntlv.set >= IPFW_MAX_SETS)
+               return (EINVAL);
        memset(&stats, 0, sizeof(stats));
 
        IPFW_UH_RLOCK(ch);
@@ -722,12 +727,45 @@ nptv6_stats(struct ip_fw_chain *ch, ip_f
        return (0);
 }
 
+/*
+ * Reset NPTv6 statistics.
+ * Data layout (v0)(current):
+ * Request: [ ipfw_obj_header ]
+ *
+ * Returns 0 on success
+ */
+static int
+nptv6_reset_stats(struct ip_fw_chain *ch, ip_fw3_opheader *op,
+    struct sockopt_data *sd)
+{
+       struct nptv6_cfg *cfg;
+       ipfw_obj_header *oh;
+
+       if (sd->valsize != sizeof(*oh))
+               return (EINVAL);
+       oh = (ipfw_obj_header *)sd->kbuf;
+       if (ipfw_check_object_name_generic(oh->ntlv.name) != 0 ||
+           oh->ntlv.set >= IPFW_MAX_SETS)
+               return (EINVAL);
+
+       IPFW_UH_WLOCK(ch);
+       cfg = nptv6_find(CHAIN_TO_SRV(ch), oh->ntlv.name, oh->ntlv.set);
+       if (cfg == NULL) {
+               IPFW_UH_WUNLOCK(ch);
+               return (ESRCH);
+       }
+       COUNTER_ARRAY_ZERO(cfg->stats, NPTV6STATS);
+       IPFW_UH_WUNLOCK(ch);
+       return (0);
+}
+
 static struct ipfw_sopt_handler        scodes[] = {
        { IP_FW_NPTV6_CREATE, 0,        HDIR_SET,       nptv6_create },
        { IP_FW_NPTV6_DESTROY,0,        HDIR_SET,       nptv6_destroy },
        { IP_FW_NPTV6_CONFIG, 0,        HDIR_BOTH,      nptv6_config },
        { IP_FW_NPTV6_LIST,   0,        HDIR_GET,       nptv6_list },
        { IP_FW_NPTV6_STATS,  0,        HDIR_GET,       nptv6_stats },
+       { IP_FW_NPTV6_RESET_STATS,0,    HDIR_SET,       nptv6_reset_stats },
 };
 
 static int
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to