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 _______________________________________________ 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"