Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 13 Aug 2016 16:45:14 +0000 (UTC)
From:      "Andrey V. Elsukov" <ae@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r304049 - in head: sbin/ipfw sys/netinet sys/netpfil/ipfw/nptv6
Message-ID:  <201608131645.u7DGjEn1059448@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: ae
Date: Sat Aug 13 16:45:14 2016
New Revision: 304049
URL: https://svnweb.freebsd.org/changeset/base/304049

Log:
  Add `stats reset` command implementation to NPTv6 module
  to be able reset statistics counters.
  
  Obtained from:	Yandex LLC
  Sponsored by:	Yandex LLC

Modified:
  head/sbin/ipfw/ipfw.8
  head/sbin/ipfw/nptv6.c
  head/sys/netinet/ip_fw.h
  head/sys/netpfil/ipfw/nptv6/nptv6.c

Modified: head/sbin/ipfw/ipfw.8
==============================================================================
--- head/sbin/ipfw/ipfw.8	Sat Aug 13 16:26:15 2016	(r304048)
+++ head/sbin/ipfw/ipfw.8	Sat Aug 13 16:45:14 2016	(r304049)
@@ -156,7 +156,7 @@ in-kernel NAT.
 .Brq Ar name | all
 .Cm destroy
 .Nm
-.Oo Cm set Ar N Oc Cm nptv6 Ar name Cm stats
+.Oo Cm set Ar N Oc Cm nptv6 Ar name Cm stats Op Cm reset
 .Ss INTERNAL DIAGNOSTICS
 .Nm
 .Cm internal iflist

Modified: head/sbin/ipfw/nptv6.c
==============================================================================
--- head/sbin/ipfw/nptv6.c	Sat Aug 13 16:26:15 2016	(r304048)
+++ head/sbin/ipfw/nptv6.c	Sat Aug 13 16:45:14 2016	(r304049)
@@ -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);
 	}
 }
 
@@ -304,6 +317,21 @@ nptv6_stats(const char *name, uint8_t se
 	    (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: head/sys/netinet/ip_fw.h
==============================================================================
--- head/sys/netinet/ip_fw.h	Sat Aug 13 16:26:15 2016	(r304048)
+++ head/sys/netinet/ip_fw.h	Sat Aug 13 16:45:14 2016	(r304049)
@@ -130,6 +130,7 @@ typedef struct _ip_fw3_opheader {
 #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

Modified: head/sys/netpfil/ipfw/nptv6/nptv6.c
==============================================================================
--- head/sys/netpfil/ipfw/nptv6/nptv6.c	Sat Aug 13 16:26:15 2016	(r304048)
+++ head/sys/netpfil/ipfw/nptv6/nptv6.c	Sat Aug 13 16:45:14 2016	(r304049)
@@ -700,6 +700,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 +725,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



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