diff options
author | Jeremie Courreges-Anglas <jca@cvs.openbsd.org> | 2017-02-09 15:23:36 +0000 |
---|---|---|
committer | Jeremie Courreges-Anglas <jca@cvs.openbsd.org> | 2017-02-09 15:23:36 +0000 |
commit | 93353c70e288507c5e9d747dfbf7efbe3a95d142 (patch) | |
tree | 573e583759a7b0c075819c2c7d2a292aaebbf650 | |
parent | 56f2e55e49aaf23d0837bf2acec5f2572233f640 (diff) |
percpu counters for raw ipv6 and icmp6 stats
ok mpi@
-rw-r--r-- | sys/netinet/icmp6.h | 95 | ||||
-rw-r--r-- | sys/netinet6/icmp6.c | 106 | ||||
-rw-r--r-- | sys/netinet6/in6_var.h | 3 | ||||
-rw-r--r-- | sys/netinet6/mld6.c | 6 | ||||
-rw-r--r-- | sys/netinet6/nd6.c | 6 | ||||
-rw-r--r-- | sys/netinet6/nd6_nbr.c | 14 | ||||
-rw-r--r-- | sys/netinet6/nd6_rtr.c | 12 | ||||
-rw-r--r-- | sys/netinet6/raw_ip6.c | 41 | ||||
-rw-r--r-- | sys/netinet6/raw_ip6.h | 25 |
9 files changed, 188 insertions, 120 deletions
diff --git a/sys/netinet/icmp6.h b/sys/netinet/icmp6.h index 17f2c2638e9..5c58798db01 100644 --- a/sys/netinet/icmp6.h +++ b/sys/netinet/icmp6.h @@ -1,4 +1,4 @@ -/* $OpenBSD: icmp6.h,v 1.42 2015/09/09 15:51:40 mpi Exp $ */ +/* $OpenBSD: icmp6.h,v 1.43 2017/02/09 15:23:35 jca Exp $ */ /* $KAME: icmp6.h,v 1.84 2003/04/23 10:26:51 itojun Exp $ */ /* @@ -457,22 +457,6 @@ struct icmp6_filter { * Variables related to this implementation * of the internet control message protocol version 6. */ -struct icmp6errstat { - u_int64_t icp6errs_dst_unreach_noroute; - u_int64_t icp6errs_dst_unreach_admin; - u_int64_t icp6errs_dst_unreach_beyondscope; - u_int64_t icp6errs_dst_unreach_addr; - u_int64_t icp6errs_dst_unreach_noport; - u_int64_t icp6errs_packet_too_big; - u_int64_t icp6errs_time_exceed_transit; - u_int64_t icp6errs_time_exceed_reassembly; - u_int64_t icp6errs_paramprob_header; - u_int64_t icp6errs_paramprob_nextheader; - u_int64_t icp6errs_paramprob_option; - u_int64_t icp6errs_redirect; /* we regard redirect as an error here */ - u_int64_t icp6errs_unknown; -}; - struct icmp6stat { /* statistics related to icmp6 packets generated */ u_int64_t icp6s_error; /* # of calls to icmp6_error */ @@ -491,25 +475,19 @@ struct icmp6stat { u_int64_t icp6s_reflect; u_int64_t icp6s_inhist[256]; u_int64_t icp6s_nd_toomanyopt; /* too many ND options */ - struct icmp6errstat icp6s_outerrhist; -#define icp6s_odst_unreach_noroute \ - icp6s_outerrhist.icp6errs_dst_unreach_noroute -#define icp6s_odst_unreach_admin icp6s_outerrhist.icp6errs_dst_unreach_admin -#define icp6s_odst_unreach_beyondscope \ - icp6s_outerrhist.icp6errs_dst_unreach_beyondscope -#define icp6s_odst_unreach_addr icp6s_outerrhist.icp6errs_dst_unreach_addr -#define icp6s_odst_unreach_noport icp6s_outerrhist.icp6errs_dst_unreach_noport -#define icp6s_opacket_too_big icp6s_outerrhist.icp6errs_packet_too_big -#define icp6s_otime_exceed_transit \ - icp6s_outerrhist.icp6errs_time_exceed_transit -#define icp6s_otime_exceed_reassembly \ - icp6s_outerrhist.icp6errs_time_exceed_reassembly -#define icp6s_oparamprob_header icp6s_outerrhist.icp6errs_paramprob_header -#define icp6s_oparamprob_nextheader \ - icp6s_outerrhist.icp6errs_paramprob_nextheader -#define icp6s_oparamprob_option icp6s_outerrhist.icp6errs_paramprob_option -#define icp6s_oredirect icp6s_outerrhist.icp6errs_redirect -#define icp6s_ounknown icp6s_outerrhist.icp6errs_unknown + u_int64_t icp6s_odst_unreach_noroute; + u_int64_t icp6s_odst_unreach_admin; + u_int64_t icp6s_odst_unreach_beyondscope; + u_int64_t icp6s_odst_unreach_addr; + u_int64_t icp6s_odst_unreach_noport; + u_int64_t icp6s_opacket_too_big; + u_int64_t icp6s_otime_exceed_transit; + u_int64_t icp6s_otime_exceed_reassembly; + u_int64_t icp6s_oparamprob_header; + u_int64_t icp6s_oparamprob_nextheader; + u_int64_t icp6s_oparamprob_option; + u_int64_t icp6s_oredirect; /* we regard redirect as an error here */ + u_int64_t icp6s_ounknown; u_int64_t icp6s_pmtuchg; /* path MTU changes */ u_int64_t icp6s_nd_badopt; /* bad ND options */ u_int64_t icp6s_badns; /* bad neighbor solicitation */ @@ -591,6 +569,51 @@ struct icmp6stat { #ifdef _KERNEL +#include <sys/percpu.h> + +enum icmp6stat_counters { + icp6s_error, + icp6s_canterror, + icp6s_toofreq, + icp6s_outhist, + icp6s_badcode = icp6s_outhist + 256, + icp6s_tooshort, + icp6s_checksum, + icp6s_badlen, + icp6s_reflect, + icp6s_inhist, + icp6s_nd_toomanyopt = icp6s_inhist + 256, + icp6s_odst_unreach_noroute, + icp6s_odst_unreach_admin, + icp6s_odst_unreach_beyondscope, + icp6s_odst_unreach_addr, + icp6s_odst_unreach_noport, + icp6s_opacket_too_big, + icp6s_otime_exceed_transit, + icp6s_otime_exceed_reassembly, + icp6s_oparamprob_header, + icp6s_oparamprob_nextheader, + icp6s_oparamprob_option, + icp6s_oredirect, + icp6s_ounknown, + icp6s_pmtuchg, + icp6s_nd_badopt, + icp6s_badns, + icp6s_badna, + icp6s_badrs, + icp6s_badra, + icp6s_badredirect, + icp6s_ncounters, +}; + +extern struct cpumem *icmp6counters; + +static inline void +icmp6stat_inc(enum icmp6stat_counters c) +{ + counters_inc(icmp6counters, c); +} + struct rtentry; struct rttimer; struct in6_multi; diff --git a/sys/netinet6/icmp6.c b/sys/netinet6/icmp6.c index d2e46d7c05d..c77c6584d79 100644 --- a/sys/netinet6/icmp6.c +++ b/sys/netinet6/icmp6.c @@ -1,4 +1,4 @@ -/* $OpenBSD: icmp6.c,v 1.199 2017/02/05 16:04:14 jca Exp $ */ +/* $OpenBSD: icmp6.c,v 1.200 2017/02/09 15:23:35 jca Exp $ */ /* $KAME: icmp6.c,v 1.217 2001/06/20 15:03:29 jinmei Exp $ */ /* @@ -102,7 +102,7 @@ #include <net/pfvar.h> #endif -struct icmp6stat icmp6stat; +struct cpumem *icmp6counters; extern struct inpcbtable rawin6pcbtable; extern int icmp6errppslim; @@ -134,7 +134,7 @@ static struct rttimer_queue *icmp6_redirect_timeout_q = NULL; /* XXX experimental, turned off */ static int icmp6_redirect_lowat = -1; -void icmp6_errcount(struct icmp6errstat *, int, int); +void icmp6_errcount(int, int); int icmp6_rip6_input(struct mbuf **, int); int icmp6_ratelimit(const struct in6_addr *, const int, const int); const char *icmp6_redirect_diag(struct in6_addr *, struct in6_addr *, @@ -150,62 +150,63 @@ icmp6_init(void) mld6_init(); icmp6_mtudisc_timeout_q = rt_timer_queue_create(ip6_mtudisc_timeout); icmp6_redirect_timeout_q = rt_timer_queue_create(icmp6_redirtimeout); + icmp6counters = counters_alloc(icp6s_ncounters); } void -icmp6_errcount(struct icmp6errstat *stat, int type, int code) +icmp6_errcount(int type, int code) { switch (type) { case ICMP6_DST_UNREACH: switch (code) { case ICMP6_DST_UNREACH_NOROUTE: - stat->icp6errs_dst_unreach_noroute++; + icmp6stat_inc(icp6s_odst_unreach_noroute); return; case ICMP6_DST_UNREACH_ADMIN: - stat->icp6errs_dst_unreach_admin++; + icmp6stat_inc(icp6s_odst_unreach_admin); return; case ICMP6_DST_UNREACH_BEYONDSCOPE: - stat->icp6errs_dst_unreach_beyondscope++; + icmp6stat_inc(icp6s_odst_unreach_beyondscope); return; case ICMP6_DST_UNREACH_ADDR: - stat->icp6errs_dst_unreach_addr++; + icmp6stat_inc(icp6s_odst_unreach_addr); return; case ICMP6_DST_UNREACH_NOPORT: - stat->icp6errs_dst_unreach_noport++; + icmp6stat_inc(icp6s_odst_unreach_noport); return; } break; case ICMP6_PACKET_TOO_BIG: - stat->icp6errs_packet_too_big++; + icmp6stat_inc(icp6s_opacket_too_big); return; case ICMP6_TIME_EXCEEDED: switch (code) { case ICMP6_TIME_EXCEED_TRANSIT: - stat->icp6errs_time_exceed_transit++; + icmp6stat_inc(icp6s_otime_exceed_transit); return; case ICMP6_TIME_EXCEED_REASSEMBLY: - stat->icp6errs_time_exceed_reassembly++; + icmp6stat_inc(icp6s_otime_exceed_reassembly); return; } break; case ICMP6_PARAM_PROB: switch (code) { case ICMP6_PARAMPROB_HEADER: - stat->icp6errs_paramprob_header++; + icmp6stat_inc(icp6s_oparamprob_header); return; case ICMP6_PARAMPROB_NEXTHEADER: - stat->icp6errs_paramprob_nextheader++; + icmp6stat_inc(icp6s_oparamprob_nextheader); return; case ICMP6_PARAMPROB_OPTION: - stat->icp6errs_paramprob_option++; + icmp6stat_inc(icp6s_oparamprob_option); return; } break; case ND_REDIRECT: - stat->icp6errs_redirect++; + icmp6stat_inc(icp6s_oredirect); return; } - stat->icp6errs_unknown++; + icmp6stat_inc(icp6s_ounknown); } /* @@ -241,10 +242,10 @@ icmp6_error(struct mbuf *m, int type, int code, int param) int off; int nxt; - icmp6stat.icp6s_error++; + icmp6stat_inc(icp6s_error); /* count per-type-code statistics */ - icmp6_errcount(&icmp6stat.icp6s_outerrhist, type, code); + icmp6_errcount(type, code); if (m->m_len < sizeof(struct ip6_hdr)) { m = m_pullup(m, sizeof(struct ip6_hdr)); @@ -291,7 +292,7 @@ icmp6_error(struct mbuf *m, int type, int code, int param) IP6_EXTHDR_GET(icp, struct icmp6_hdr *, m, off, sizeof(*icp)); if (icp == NULL) { - icmp6stat.icp6s_tooshort++; + icmp6stat_inc(icp6s_tooshort); return; } if (icp->icmp6_type < ICMP6_ECHO_REQUEST || @@ -301,7 +302,7 @@ icmp6_error(struct mbuf *m, int type, int code, int param) * Special case: for redirect (which is * informational) we must not send icmp6 error. */ - icmp6stat.icp6s_canterror++; + icmp6stat_inc(icp6s_canterror); goto freeit; } else { /* ICMPv6 informational - send the error */ @@ -315,7 +316,7 @@ icmp6_error(struct mbuf *m, int type, int code, int param) /* Finally, do rate limitation check. */ if (icmp6_ratelimit(&oip6->ip6_src, type, code)) { - icmp6stat.icp6s_toofreq++; + icmp6stat_inc(icp6s_toofreq); goto freeit; } @@ -358,7 +359,7 @@ icmp6_error(struct mbuf *m, int type, int code, int param) */ m->m_pkthdr.ph_ifidx = 0; - icmp6stat.icp6s_outhist[type]++; + icmp6stat_inc(icp6s_outhist + type); icmp6_reflect(m, sizeof(struct ip6_hdr)); /* header order: IPv6 - ICMPv6 */ return; @@ -394,7 +395,7 @@ icmp6_input(struct mbuf **mp, int *offp, int proto) ip6 = mtod(m, struct ip6_hdr *); if (icmp6len < sizeof(struct icmp6_hdr)) { - icmp6stat.icp6s_tooshort++; + icmp6stat_inc(icp6s_tooshort); goto freeit; } @@ -403,7 +404,7 @@ icmp6_input(struct mbuf **mp, int *offp, int proto) */ IP6_EXTHDR_GET(icmp6, struct icmp6_hdr *, m, off, sizeof(*icmp6)); if (icmp6 == NULL) { - icmp6stat.icp6s_tooshort++; + icmp6stat_inc(icp6s_tooshort); return IPPROTO_DONE; } code = icmp6->icmp6_code; @@ -413,7 +414,7 @@ icmp6_input(struct mbuf **mp, int *offp, int proto) "ICMP6 checksum error(%d|%x) %s\n", icmp6->icmp6_type, sum, inet_ntop(AF_INET6, &ip6->ip6_src, src, sizeof(src)))); - icmp6stat.icp6s_checksum++; + icmp6stat_inc(icp6s_checksum); goto freeit; } @@ -450,7 +451,7 @@ icmp6_input(struct mbuf **mp, int *offp, int proto) if_put(ifp); #endif - icmp6stat.icp6s_inhist[icmp6->icmp6_type]++; + icmp6stat_inc(icp6s_inhist + icmp6->icmp6_type); switch (icmp6->icmp6_type) { case ICMP6_DST_UNREACH: @@ -595,8 +596,8 @@ icmp6_input(struct mbuf **mp, int *offp, int proto) nicmp6->icmp6_type = ICMP6_ECHO_REPLY; nicmp6->icmp6_code = 0; if (n) { - icmp6stat.icp6s_reflect++; - icmp6stat.icp6s_outhist[ICMP6_ECHO_REPLY]++; + icmp6stat_inc(icp6s_reflect); + icmp6stat_inc(icp6s_outhist + ICMP6_ECHO_REPLY); icmp6_reflect(n, noff); } if (!m) @@ -745,11 +746,11 @@ deliver: break; badcode: - icmp6stat.icp6s_badcode++; + icmp6stat_inc(icp6s_badcode); break; badlen: - icmp6stat.icp6s_badlen++; + icmp6stat_inc(icp6s_badlen); break; } @@ -775,13 +776,13 @@ icmp6_notify_error(struct mbuf *m, int off, int icmp6len, int code) struct sockaddr_in6 icmp6src, icmp6dst; if (icmp6len < sizeof(struct icmp6_hdr) + sizeof(struct ip6_hdr)) { - icmp6stat.icp6s_tooshort++; + icmp6stat_inc(icp6s_tooshort); goto freeit; } IP6_EXTHDR_GET(icmp6, struct icmp6_hdr *, m, off, sizeof(*icmp6) + sizeof(struct ip6_hdr)); if (icmp6 == NULL) { - icmp6stat.icp6s_tooshort++; + icmp6stat_inc(icp6s_tooshort); return (-1); } eip6 = (struct ip6_hdr *)(icmp6 + 1); @@ -810,7 +811,7 @@ icmp6_notify_error(struct mbuf *m, int off, int icmp6len, int code) IP6_EXTHDR_GET(eh, struct ip6_ext *, m, eoff, sizeof(*eh)); if (eh == NULL) { - icmp6stat.icp6s_tooshort++; + icmp6stat_inc(icp6s_tooshort); return (-1); } @@ -832,7 +833,7 @@ icmp6_notify_error(struct mbuf *m, int off, int icmp6len, int code) IP6_EXTHDR_GET(rth, struct ip6_rthdr *, m, eoff, sizeof(*rth)); if (rth == NULL) { - icmp6stat.icp6s_tooshort++; + icmp6stat_inc(icp6s_tooshort); return (-1); } rthlen = (rth->ip6r_len + 1) << 3; @@ -852,7 +853,7 @@ icmp6_notify_error(struct mbuf *m, int off, int icmp6len, int code) struct ip6_rthdr0 *, m, eoff, rthlen); if (rth0 == NULL) { - icmp6stat.icp6s_tooshort++; + icmp6stat_inc(icp6s_tooshort); return (-1); } /* just ignore a bogus header */ @@ -867,7 +868,7 @@ icmp6_notify_error(struct mbuf *m, int off, int icmp6len, int code) IP6_EXTHDR_GET(fh, struct ip6_frag *, m, eoff, sizeof(*fh)); if (fh == NULL) { - icmp6stat.icp6s_tooshort++; + icmp6stat_inc(icp6s_tooshort); return (-1); } /* @@ -898,7 +899,7 @@ icmp6_notify_error(struct mbuf *m, int off, int icmp6len, int code) IP6_EXTHDR_GET(icmp6, struct icmp6_hdr *, m, off, sizeof(*icmp6) + sizeof(struct ip6_hdr)); if (icmp6 == NULL) { - icmp6stat.icp6s_tooshort++; + icmp6stat_inc(icp6s_tooshort); return (-1); } @@ -1022,7 +1023,7 @@ icmp6_mtudisc_update(struct ip6ctlparam *ip6cp, int validated) ifp = if_get(rt->rt_ifidx); if (ifp != NULL && mtu < ifp->if_mtu) { - icmp6stat.icp6s_pmtuchg++; + icmp6stat_inc(icp6s_pmtuchg); rt->rt_rmx.rmx_mtu = mtu; } if_put(ifp); @@ -1357,7 +1358,7 @@ icmp6_redirect_input(struct mbuf *m, int off) IP6_EXTHDR_GET(nd_rd, struct nd_redirect *, m, off, icmp6len); if (nd_rd == NULL) { - icmp6stat.icp6s_tooshort++; + icmp6stat_inc(icp6s_tooshort); if_put(ifp); return; } @@ -1538,7 +1539,7 @@ icmp6_redirect_input(struct mbuf *m, int off) bad: if_put(ifp); - icmp6stat.icp6s_badredirect++; + icmp6stat_inc(icp6s_badredirect); m_freem(m); } @@ -1556,7 +1557,7 @@ icmp6_redirect_output(struct mbuf *m0, struct rtentry *rt) u_char *p; struct sockaddr_in6 src_sa; - icmp6_errcount(&icmp6stat.icp6s_outerrhist, ND_REDIRECT, 0); + icmp6_errcount(ND_REDIRECT, 0); /* if we are not router, we don't send icmp6 redirect */ if (!ip6_forwarding) @@ -1791,7 +1792,7 @@ noredhdropt: /* send the packet to outside... */ ip6_output(m, NULL, NULL, 0, NULL, NULL); - icmp6stat.icp6s_outhist[ND_REDIRECT]++; + icmp6stat_inc(icp6s_outhist + ND_REDIRECT); if_put(ifp); return; @@ -1987,6 +1988,22 @@ icmp6_redirect_timeout(struct rtentry *rt, struct rttimer *r) int *icmpv6ctl_vars[ICMPV6CTL_MAXID] = ICMPV6CTL_VARS; int +icmp6_sysctl_icmp6stat(void *oldp, size_t *oldlenp, void *newp) +{ + struct icmp6stat *icmp6stat; + int ret; + + CTASSERT(sizeof(*icmp6stat) == icp6s_ncounters * sizeof(uint64_t)); + icmp6stat = malloc(sizeof(*icmp6stat), M_TEMP, M_WAITOK); + counters_read(icmp6counters, (uint64_t *)icmp6stat, icp6s_ncounters); + ret = sysctl_rdstruct(oldp, oldlenp, newp, + icmp6stat, sizeof(*icmp6stat)); + free(icmp6stat, M_TEMP, sizeof(*icmp6stat)); + + return (ret); +} + +int icmp6_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, size_t newlen) { @@ -1997,8 +2014,7 @@ icmp6_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, switch (name[0]) { case ICMPV6CTL_STATS: - return sysctl_rdstruct(oldp, oldlenp, newp, - &icmp6stat, sizeof(icmp6stat)); + return icmp6_sysctl_icmp6stat(oldp, oldlenp, newp); case ICMPV6CTL_ND6_DRLIST: case ICMPV6CTL_ND6_PRLIST: return nd6_sysctl(name[0], oldp, oldlenp, newp, newlen); diff --git a/sys/netinet6/in6_var.h b/sys/netinet6/in6_var.h index 3dc4d8c0310..c6d6d1ef061 100644 --- a/sys/netinet6/in6_var.h +++ b/sys/netinet6/in6_var.h @@ -1,4 +1,4 @@ -/* $OpenBSD: in6_var.h,v 1.64 2016/07/05 10:17:14 mpi Exp $ */ +/* $OpenBSD: in6_var.h,v 1.65 2017/02/09 15:23:35 jca Exp $ */ /* $KAME: in6_var.h,v 1.55 2001/02/16 12:49:45 itojun Exp $ */ /* @@ -334,7 +334,6 @@ struct in6_aliasreq { TAILQ_HEAD(in6_ifaddrhead, in6_ifaddr); extern struct in6_ifaddrhead in6_ifaddr; -extern struct icmp6stat icmp6stat; /* * Multi-cast membership entry. One for each group/ifp that a PCB diff --git a/sys/netinet6/mld6.c b/sys/netinet6/mld6.c index 8b84d34c751..63d1d3e46b2 100644 --- a/sys/netinet6/mld6.c +++ b/sys/netinet6/mld6.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mld6.c,v 1.49 2016/12/21 12:12:13 mpi Exp $ */ +/* $OpenBSD: mld6.c,v 1.50 2017/02/09 15:23:35 jca Exp $ */ /* $KAME: mld6.c,v 1.26 2001/02/16 14:50:35 itojun Exp $ */ /* @@ -165,7 +165,7 @@ mld6_input(struct mbuf *m, int off) IP6_EXTHDR_GET(mldh, struct mld_hdr *, m, off, sizeof(*mldh)); if (mldh == NULL) { - icmp6stat.icp6s_tooshort++; + icmp6stat_inc(icp6s_tooshort); return; } @@ -454,7 +454,7 @@ mld6_sendpkt(struct in6_multi *in6m, int type, const struct in6_addr *dst) im6o.im6o_loop = (ip6_mrouter != NULL); #endif - icmp6stat.icp6s_outhist[type]++; + icmp6stat_inc(icp6s_outhist + type); ip6_output(mh, &ip6_opts, NULL, ia6 ? 0 : IPV6_UNSPECSRC, &im6o, NULL); } diff --git a/sys/netinet6/nd6.c b/sys/netinet6/nd6.c index 082e93021a4..30d72dd6dfc 100644 --- a/sys/netinet6/nd6.c +++ b/sys/netinet6/nd6.c @@ -1,4 +1,4 @@ -/* $OpenBSD: nd6.c,v 1.202 2016/12/27 18:45:01 bluhm Exp $ */ +/* $OpenBSD: nd6.c,v 1.203 2017/02/09 15:23:35 jca Exp $ */ /* $KAME: nd6.c,v 1.280 2002/06/08 19:52:07 itojun Exp $ */ /* @@ -249,7 +249,7 @@ nd6_options(union nd_opts *ndopts) * Message validation requires that all included * options have a length that is greater than zero. */ - icmp6stat.icp6s_nd_badopt++; + icmp6stat_inc(icp6s_nd_badopt); bzero(ndopts, sizeof(*ndopts)); return -1; } @@ -293,7 +293,7 @@ nd6_options(union nd_opts *ndopts) skip1: i++; if (i > nd6_maxndopt) { - icmp6stat.icp6s_nd_toomanyopt++; + icmp6stat_inc(icp6s_nd_toomanyopt); nd6log((LOG_INFO, "too many loop in nd opt\n")); break; } diff --git a/sys/netinet6/nd6_nbr.c b/sys/netinet6/nd6_nbr.c index d937598bbca..fef9d7e0a93 100644 --- a/sys/netinet6/nd6_nbr.c +++ b/sys/netinet6/nd6_nbr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: nd6_nbr.c,v 1.114 2017/01/03 13:32:51 bluhm Exp $ */ +/* $OpenBSD: nd6_nbr.c,v 1.115 2017/02/09 15:23:35 jca Exp $ */ /* $KAME: nd6_nbr.c,v 1.61 2001/02/10 16:06:14 jinmei Exp $ */ /* @@ -118,7 +118,7 @@ nd6_ns_input(struct mbuf *m, int off, int icmp6len) IP6_EXTHDR_GET(nd_ns, struct nd_neighbor_solicit *, m, off, icmp6len); if (nd_ns == NULL) { - icmp6stat.icp6s_tooshort++; + icmp6stat_inc(icp6s_tooshort); if_put(ifp); return; } @@ -339,7 +339,7 @@ nd6_ns_input(struct mbuf *m, int off, int icmp6len) inet_ntop(AF_INET6, &daddr6, addr, sizeof(addr)))); nd6log((LOG_ERR, "nd6_ns_input: tgt=%s\n", inet_ntop(AF_INET6, &taddr6, addr, sizeof(addr)))); - icmp6stat.icp6s_badns++; + icmp6stat_inc(icp6s_badns); m_freem(m); if_put(ifp); } @@ -532,7 +532,7 @@ nd6_ns_output(struct ifnet *ifp, struct in6_addr *daddr6, m->m_pkthdr.csum_flags |= M_ICMP_CSUM_OUT; ip6_output(m, NULL, NULL, dad ? IPV6_UNSPECSRC : 0, &im6o, NULL); - icmp6stat.icp6s_outhist[ND_NEIGHBOR_SOLICIT]++; + icmp6stat_inc(icp6s_outhist + ND_NEIGHBOR_SOLICIT); return; bad: @@ -589,7 +589,7 @@ nd6_na_input(struct mbuf *m, int off, int icmp6len) IP6_EXTHDR_GET(nd_na, struct nd_neighbor_advert *, m, off, icmp6len); if (nd_na == NULL) { - icmp6stat.icp6s_tooshort++; + icmp6stat_inc(icp6s_tooshort); if_put(ifp); return; } @@ -875,7 +875,7 @@ nd6_na_input(struct mbuf *m, int off, int icmp6len) return; bad: - icmp6stat.icp6s_badna++; + icmp6stat_inc(icp6s_badna); m_freem(m); if_put(ifp); } @@ -1037,7 +1037,7 @@ nd6_na_output(struct ifnet *ifp, struct in6_addr *daddr6, m->m_pkthdr.csum_flags |= M_ICMP_CSUM_OUT; ip6_output(m, NULL, NULL, 0, &im6o, NULL); - icmp6stat.icp6s_outhist[ND_NEIGHBOR_ADVERT]++; + icmp6stat_inc(icp6s_outhist+ ND_NEIGHBOR_ADVERT); return; bad: diff --git a/sys/netinet6/nd6_rtr.c b/sys/netinet6/nd6_rtr.c index 4885c37cdb9..8dd1a2ed0e9 100644 --- a/sys/netinet6/nd6_rtr.c +++ b/sys/netinet6/nd6_rtr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: nd6_rtr.c,v 1.154 2016/12/22 13:39:32 mpi Exp $ */ +/* $OpenBSD: nd6_rtr.c,v 1.155 2017/02/09 15:23:35 jca Exp $ */ /* $KAME: nd6_rtr.c,v 1.97 2001/02/07 11:09:13 itojun Exp $ */ /* @@ -150,7 +150,7 @@ nd6_rs_input(struct mbuf *m, int off, int icmp6len) IP6_EXTHDR_GET(nd_rs, struct nd_router_solicit *, m, off, icmp6len); if (nd_rs == NULL) { - icmp6stat.icp6s_tooshort++; + icmp6stat_inc(icp6s_tooshort); return; } @@ -190,7 +190,7 @@ nd6_rs_input(struct mbuf *m, int off, int icmp6len) return; bad: - icmp6stat.icp6s_badrs++; + icmp6stat_inc(icp6s_badrs); m_freem(m); } @@ -276,7 +276,7 @@ nd6_rs_output(struct ifnet* ifp, struct in6_ifaddr *ia6) ip6_output(m, NULL, NULL, 0, &im6o, NULL); - icmp6stat.icp6s_outhist[ND_ROUTER_SOLICIT]++; + icmp6stat_inc(icp6s_outhist + ND_ROUTER_SOLICIT); } void @@ -412,7 +412,7 @@ nd6_ra_input(struct mbuf *m, int off, int icmp6len) IP6_EXTHDR_GET(nd_ra, struct nd_router_advert *, m, off, icmp6len); if (nd_ra == NULL) { - icmp6stat.icp6s_tooshort++; + icmp6stat_inc(icp6s_tooshort); if_put(ifp); return; } @@ -570,7 +570,7 @@ nd6_ra_input(struct mbuf *m, int off, int icmp6len) return; bad: - icmp6stat.icp6s_badra++; + icmp6stat_inc(icp6s_badra); if_put(ifp); m_freem(m); } diff --git a/sys/netinet6/raw_ip6.c b/sys/netinet6/raw_ip6.c index fd1dc59b5a6..23c46ecb628 100644 --- a/sys/netinet6/raw_ip6.c +++ b/sys/netinet6/raw_ip6.c @@ -1,4 +1,4 @@ -/* $OpenBSD: raw_ip6.c,v 1.105 2017/02/05 16:04:14 jca Exp $ */ +/* $OpenBSD: raw_ip6.c,v 1.106 2017/02/09 15:23:35 jca Exp $ */ /* $KAME: raw_ip6.c,v 1.69 2001/03/04 15:55:44 itojun Exp $ */ /* @@ -103,7 +103,7 @@ struct inpcbtable rawin6pcbtable; -struct rip6stat rip6stat; +struct cpumem *rip6counters; /* * Initialize raw connection block queue. @@ -111,8 +111,8 @@ struct rip6stat rip6stat; void rip6_init(void) { - in_pcbinit(&rawin6pcbtable, 1); + rip6counters = counters_alloc(rip6s_ncounters); } int @@ -125,7 +125,7 @@ rip6_input(struct mbuf **mp, int *offp, int proto) struct sockaddr_in6 rip6src; struct mbuf *opts = NULL; - rip6stat.rip6s_ipackets++; + rip6stat_inc(rip6s_ipackets); /* Be proactive about malicious use of IPv4 mapped address */ if (IN6_IS_ADDR_V4MAPPED(&ip6->ip6_src) || @@ -171,10 +171,10 @@ rip6_input(struct mbuf **mp, int *offp, int proto) !IN6_ARE_ADDR_EQUAL(&in6p->inp_faddr6, &ip6->ip6_src)) continue; if (in6p->inp_cksum6 != -1) { - rip6stat.rip6s_isum++; + rip6stat_inc(rip6s_isum); if (in6_cksum(m, proto, *offp, m->m_pkthdr.len - *offp)) { - rip6stat.rip6s_badsum++; + rip6stat_inc(rip6s_badsum); continue; } } @@ -190,7 +190,7 @@ rip6_input(struct mbuf **mp, int *offp, int proto) /* should notify about lost packet */ m_freem(n); m_freem(opts); - rip6stat.rip6s_fullsock++; + rip6stat_inc(rip6s_fullsock); } else sorwakeup(last->inp_socket); opts = NULL; @@ -207,16 +207,16 @@ rip6_input(struct mbuf **mp, int *offp, int proto) sin6tosa(&rip6src), m, opts) == 0) { m_freem(m); m_freem(opts); - rip6stat.rip6s_fullsock++; + rip6stat_inc(rip6s_fullsock); } else sorwakeup(last->inp_socket); } else { struct counters_ref ref; uint64_t *counters; - rip6stat.rip6s_nosock++; + rip6stat_inc(rip6s_nosock); if (m->m_flags & M_MCAST) - rip6stat.rip6s_nosockmcast++; + rip6stat_inc(rip6s_nosockmcast); if (proto == IPPROTO_NONE) m_freem(m); else { @@ -457,9 +457,9 @@ rip6_output(struct mbuf *m, ...) error = ip6_output(m, optp, &in6p->inp_route6, flags, in6p->inp_moptions6, in6p); if (so->so_proto->pr_protocol == IPPROTO_ICMPV6) { - icmp6stat.icp6s_outhist[type]++; + icmp6stat_inc(icp6s_outhist + type); } else - rip6stat.rip6s_opackets++; + rip6stat_inc(rip6s_opackets); goto freectl; @@ -769,6 +769,18 @@ rip6_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam, } int +rip6_sysctl_rip6stat(void *oldp, size_t *oldplen, void *newp) +{ + struct rip6stat rip6stat; + + CTASSERT(sizeof(rip6stat) == rip6s_ncounters * sizeof(uint64_t)); + counters_read(ip6counters, (uint64_t *)&rip6stat, rip6s_ncounters); + + return (sysctl_rdstruct(oldp, oldplen, newp, + &rip6stat, sizeof(rip6stat))); +} + +int rip6_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, size_t newlen) { @@ -778,10 +790,7 @@ rip6_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, switch (name[0]) { case RIPV6CTL_STATS: - if (newp != NULL) - return (EPERM); - return (sysctl_struct(oldp, oldlenp, newp, newlen, - &rip6stat, sizeof(rip6stat))); + return (rip6_sysctl_rip6stat(oldp, oldlenp, newp)); default: return (EOPNOTSUPP); } diff --git a/sys/netinet6/raw_ip6.h b/sys/netinet6/raw_ip6.h index d81b1451b4d..d972e6a14e9 100644 --- a/sys/netinet6/raw_ip6.h +++ b/sys/netinet6/raw_ip6.h @@ -1,4 +1,4 @@ -/* $OpenBSD: raw_ip6.h,v 1.3 2007/12/14 18:33:42 deraadt Exp $ */ +/* $OpenBSD: raw_ip6.h,v 1.4 2017/02/09 15:23:35 jca Exp $ */ /* $KAME: raw_ip6.h,v 1.2 2001/05/27 13:28:35 itojun Exp $ */ /* @@ -59,7 +59,28 @@ struct rip6stat { } #ifdef _KERNEL -extern struct rip6stat rip6stat; + +#include <sys/percpu.h> + +enum rip6stat_counters { + rip6s_ipackets, + rip6s_isum, + rip6s_badsum, + rip6s_nosock, + rip6s_nosockmcast, + rip6s_fullsock, + rip6s_opackets, + rip6s_ncounters, +}; + +extern struct cpumem *rip6counters; + +static inline void +rip6stat_inc(enum rip6stat_counters c) +{ + counters_inc(rip6counters, c); +} + #endif #endif |