diff options
author | Jeremie Courreges-Anglas <jca@cvs.openbsd.org> | 2017-02-05 16:04:15 +0000 |
---|---|---|
committer | Jeremie Courreges-Anglas <jca@cvs.openbsd.org> | 2017-02-05 16:04:15 +0000 |
commit | a0fe76973a89628bbcd7a93577076e67e111a4a4 (patch) | |
tree | 627e4d024b0b67aff06231ec1d2f58ae6f4b8a80 | |
parent | daf9ee77f00685cfb1100181f3ecec6af00c6ee1 (diff) |
Use percpu counters for ip6stat
Try to follow the existing examples. Some notes:
- don't implement counters_dec() yet, which could be used in two
similar chunks of code. Let's see if there are more users first.
- stop incrementing IPv6-specific mbuf stats, IPv4 has no equivalent.
Input from mpi@, ok bluhm@ mpi@
-rw-r--r-- | sys/net/if_bridge.c | 6 | ||||
-rw-r--r-- | sys/net/pf.c | 4 | ||||
-rw-r--r-- | sys/netinet/ipsec_input.c | 6 | ||||
-rw-r--r-- | sys/netinet6/dest6.c | 4 | ||||
-rw-r--r-- | sys/netinet6/frag6.c | 18 | ||||
-rw-r--r-- | sys/netinet6/icmp6.c | 9 | ||||
-rw-r--r-- | sys/netinet6/in6.c | 14 | ||||
-rw-r--r-- | sys/netinet6/ip6_forward.c | 16 | ||||
-rw-r--r-- | sys/netinet6/ip6_input.c | 118 | ||||
-rw-r--r-- | sys/netinet6/ip6_mroute.c | 4 | ||||
-rw-r--r-- | sys/netinet6/ip6_output.c | 18 | ||||
-rw-r--r-- | sys/netinet6/ip6_var.h | 62 | ||||
-rw-r--r-- | sys/netinet6/raw_ip6.c | 9 | ||||
-rw-r--r-- | sys/netinet6/route6.c | 6 |
14 files changed, 180 insertions, 114 deletions
diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c index 43c8e5e478c..4e27e3f249f 100644 --- a/sys/net/if_bridge.c +++ b/sys/net/if_bridge.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_bridge.c,v 1.293 2017/01/24 10:08:30 krw Exp $ */ +/* $OpenBSD: if_bridge.c,v 1.294 2017/02/05 16:04:14 jca Exp $ */ /* * Copyright (c) 1999, 2000 Jason L. Wright (jason@thought.net) @@ -1692,7 +1692,7 @@ bridge_ip(struct bridge_softc *sc, int dir, struct ifnet *ifp, if (m->m_len < sizeof(struct ip6_hdr)) { if ((m = m_pullup(m, sizeof(struct ip6_hdr))) == NULL) { - ip6stat.ip6s_toosmall++; + ip6stat_inc(ip6s_toosmall); return (NULL); } } @@ -1700,7 +1700,7 @@ bridge_ip(struct bridge_softc *sc, int dir, struct ifnet *ifp, ip6 = mtod(m, struct ip6_hdr *); if ((ip6->ip6_vfc & IPV6_VERSION_MASK) != IPV6_VERSION) { - ip6stat.ip6s_badvers++; + ip6stat_inc(ip6s_badvers); goto dropit; } diff --git a/sys/net/pf.c b/sys/net/pf.c index 3895dd18d4d..b4e598716e9 100644 --- a/sys/net/pf.c +++ b/sys/net/pf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pf.c,v 1.1013 2017/01/30 17:52:24 benno Exp $ */ +/* $OpenBSD: pf.c,v 1.1014 2017/02/05 16:04:14 jca Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -5974,7 +5974,7 @@ pf_route6(struct pf_pdesc *pd, struct pf_rule *r, struct pf_state *s) rt = rtalloc(sin6tosa(dst), RT_RESOLVE, rtableid); if (!rtisvalid(rt)) { - ip6stat.ip6s_noroute++; + ip6stat_inc(ip6s_noroute); goto bad; } diff --git a/sys/netinet/ipsec_input.c b/sys/netinet/ipsec_input.c index c5952707aaa..188b21885ca 100644 --- a/sys/netinet/ipsec_input.c +++ b/sys/netinet/ipsec_input.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ipsec_input.c,v 1.141 2017/01/29 19:58:47 bluhm Exp $ */ +/* $OpenBSD: ipsec_input.c,v 1.142 2017/02/05 16:04:14 jca Exp $ */ /* * The authors of this code are John Ioannidis (ji@tla.org), * Angelos D. Keromytis (kermit@csd.uch.gr) and @@ -985,7 +985,7 @@ ah6_input_cb(struct mbuf *m, int off, int protoff) */ while (nxt != IPPROTO_DONE) { if (ip6_hdrnestlimit && (++nest > ip6_hdrnestlimit)) { - ip6stat.ip6s_toomanyhdr++; + ip6stat_inc(ip6s_toomanyhdr); goto bad; } @@ -994,7 +994,7 @@ ah6_input_cb(struct mbuf *m, int off, int protoff) * more sanity checks in header chain processing. */ if (m->m_pkthdr.len < off) { - ip6stat.ip6s_tooshort++; + ip6stat_inc(ip6s_tooshort); goto bad; } nxt = (*inet6sw[ip6_protox[nxt]].pr_input)(&m, &off, nxt); diff --git a/sys/netinet6/dest6.c b/sys/netinet6/dest6.c index f00e12e4352..05f0cc5edc7 100644 --- a/sys/netinet6/dest6.c +++ b/sys/netinet6/dest6.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dest6.c,v 1.15 2015/03/14 03:38:52 jsg Exp $ */ +/* $OpenBSD: dest6.c,v 1.16 2017/02/05 16:04:14 jca Exp $ */ /* $KAME: dest6.c,v 1.25 2001/02/22 01:39:16 itojun Exp $ */ /* @@ -73,7 +73,7 @@ dest6_input(struct mbuf **mp, int *offp, int proto) for (optlen = 0; dstoptlen > 0; dstoptlen -= optlen, opt += optlen) { if (*opt != IP6OPT_PAD1 && (dstoptlen < IP6OPT_MINLEN || *(opt + 1) + 2 > dstoptlen)) { - ip6stat.ip6s_toosmall++; + ip6stat_inc(ip6s_toosmall); goto bad; } diff --git a/sys/netinet6/frag6.c b/sys/netinet6/frag6.c index a8cff587aeb..395051928f8 100644 --- a/sys/netinet6/frag6.c +++ b/sys/netinet6/frag6.c @@ -1,4 +1,4 @@ -/* $OpenBSD: frag6.c,v 1.71 2016/11/28 11:12:45 mpi Exp $ */ +/* $OpenBSD: frag6.c,v 1.72 2017/02/05 16:04:14 jca Exp $ */ /* $KAME: frag6.c,v 1.40 2002/05/27 21:40:31 itojun Exp $ */ /* @@ -190,7 +190,7 @@ frag6_input(struct mbuf **mp, int *offp, int proto) return IPPROTO_DONE; } - ip6stat.ip6s_fragments++; + ip6stat_inc(ip6s_fragments); /* offset now points to data portion */ offset += sizeof(struct ip6_frag); @@ -203,7 +203,7 @@ frag6_input(struct mbuf **mp, int *offp, int proto) */ fragoff = ntohs(ip6f->ip6f_offlg & IP6F_OFF_MASK); if (fragoff == 0 && !(ip6f->ip6f_offlg & IP6F_MORE_FRAG)) { - ip6stat.ip6s_reassembled++; + ip6stat_inc(ip6s_reassembled); *offp = offset; return ip6f->ip6f_nxt; } @@ -496,7 +496,7 @@ frag6_input(struct mbuf **mp, int *offp, int proto) m->m_pkthdr.len = plen; } - ip6stat.ip6s_reassembled++; + ip6stat_inc(ip6s_reassembled); /* * Tell launch routine the next header @@ -514,14 +514,14 @@ frag6_input(struct mbuf **mp, int *offp, int proto) m_freem(IP6_REASS_MBUF(af6)); free(af6, M_FTABLE, sizeof(*af6)); } - ip6stat.ip6s_fragdropped += q6->ip6q_nfrag; + ip6stat_add(ip6s_fragdropped, q6->ip6q_nfrag); TAILQ_REMOVE(&frag6_queue, q6, ip6q_queue); frag6_nfrags -= q6->ip6q_nfrag; free(q6, M_FTABLE, sizeof(*q6)); frag6_nfragpackets--; dropfrag: - ip6stat.ip6s_fragdropped++; + ip6stat_inc(ip6s_fragdropped); m_freem(m); IP6Q_UNLOCK(); return IPPROTO_DONE; @@ -608,7 +608,7 @@ frag6_slowtimo(void) IP6Q_LOCK(); TAILQ_FOREACH_SAFE(q6, &frag6_queue, ip6q_queue, nq6) if (--q6->ip6q_ttl == 0) { - ip6stat.ip6s_fragtimeout++; + ip6stat_inc(ip6s_fragtimeout); frag6_freef(q6); } @@ -619,7 +619,7 @@ frag6_slowtimo(void) */ while (frag6_nfragpackets > (u_int)ip6_maxfragpackets && !TAILQ_EMPTY(&frag6_queue)) { - ip6stat.ip6s_fragoverflow++; + ip6stat_inc(ip6s_fragoverflow); frag6_freef(TAILQ_LAST(&frag6_queue, ip6q_head)); } IP6Q_UNLOCK(); @@ -636,7 +636,7 @@ frag6_drain(void) if (ip6q_lock_try() == 0) return; while ((q6 = TAILQ_FIRST(&frag6_queue)) != NULL) { - ip6stat.ip6s_fragdropped++; + ip6stat_inc(ip6s_fragdropped); frag6_freef(q6); } IP6Q_UNLOCK(); diff --git a/sys/netinet6/icmp6.c b/sys/netinet6/icmp6.c index 5041109341c..d2e46d7c05d 100644 --- a/sys/netinet6/icmp6.c +++ b/sys/netinet6/icmp6.c @@ -1,4 +1,4 @@ -/* $OpenBSD: icmp6.c,v 1.198 2017/02/01 20:59:47 dhill Exp $ */ +/* $OpenBSD: icmp6.c,v 1.199 2017/02/05 16:04:14 jca Exp $ */ /* $KAME: icmp6.c,v 1.217 2001/06/20 15:03:29 jinmei Exp $ */ /* @@ -1124,8 +1124,13 @@ icmp6_rip6_input(struct mbuf **mp, int off) } else sorwakeup(last->inp_socket); } else { + struct counters_ref ref; + uint64_t *counters; + m_freem(m); - ip6stat.ip6s_delivered--; + counters = counters_enter(&ref, ip6counters); + counters[ip6s_delivered]--; + counters_leave(&ref, ip6counters); } return IPPROTO_DONE; } diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c index 97fdcbb500c..d67a1844d84 100644 --- a/sys/netinet6/in6.c +++ b/sys/netinet6/in6.c @@ -1,4 +1,4 @@ -/* $OpenBSD: in6.c,v 1.196 2016/12/21 12:11:12 mpi Exp $ */ +/* $OpenBSD: in6.c,v 1.197 2017/02/05 16:04:14 jca Exp $ */ /* $KAME: in6.c,v 1.372 2004/06/14 08:14:21 itojun Exp $ */ /* @@ -1839,20 +1839,20 @@ in6_ifawithscope(struct ifnet *oifp, struct in6_addr *dst, u_int rdomain) /* count statistics for future improvements */ if (ia6_best == NULL) - ip6stat.ip6s_sources_none++; + ip6stat_inc(ip6s_sources_none); else { if (oifp == ia6_best->ia_ifp) - ip6stat.ip6s_sources_sameif[best_scope]++; + ip6stat_inc(ip6s_sources_sameif + best_scope); else - ip6stat.ip6s_sources_otherif[best_scope]++; + ip6stat_inc(ip6s_sources_otherif + best_scope); if (best_scope == dst_scope) - ip6stat.ip6s_sources_samescope[best_scope]++; + ip6stat_inc(ip6s_sources_samescope + best_scope); else - ip6stat.ip6s_sources_otherscope[best_scope]++; + ip6stat_inc(ip6s_sources_otherscope + best_scope); if ((ia6_best->ia6_flags & IN6_IFF_DEPRECATED) != 0) - ip6stat.ip6s_sources_deprecated[best_scope]++; + ip6stat_inc(ip6s_sources_deprecated + best_scope); } return (ia6_best); diff --git a/sys/netinet6/ip6_forward.c b/sys/netinet6/ip6_forward.c index 9d9bfdccc97..81e2a80124d 100644 --- a/sys/netinet6/ip6_forward.c +++ b/sys/netinet6/ip6_forward.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip6_forward.c,v 1.93 2016/10/03 12:33:21 mpi Exp $ */ +/* $OpenBSD: ip6_forward.c,v 1.94 2017/02/05 16:04:14 jca Exp $ */ /* $KAME: ip6_forward.c,v 1.75 2001/06/29 12:42:13 jinmei Exp $ */ /* @@ -103,7 +103,7 @@ ip6_forward(struct mbuf *m, struct rtentry *rt, int srcrt) if ((m->m_flags & (M_BCAST|M_MCAST)) != 0 || IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst) || IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_src)) { - ip6stat.ip6s_cantforward++; + ip6stat_inc(ip6s_cantforward); if (ip6_log_time + ip6_log_interval < time_uptime) { ip6_log_time = time_uptime; inet_ntop(AF_INET6, &ip6->ip6_src, src6, sizeof(src6)); @@ -171,7 +171,7 @@ reroute: rt = rtalloc_mpath(sin6tosa(dst), &ip6->ip6_src.s6_addr32[0], m->m_pkthdr.ph_rtableid); if (rt == NULL) { - ip6stat.ip6s_noroute++; + ip6stat_inc(ip6s_noroute); if (mcopy) { icmp6_error(mcopy, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_NOROUTE, 0); @@ -190,8 +190,8 @@ reroute: */ if (in6_addr2scopeid(m->m_pkthdr.ph_ifidx, &ip6->ip6_src) != in6_addr2scopeid(rt->rt_ifidx, &ip6->ip6_src)) { - ip6stat.ip6s_cantforward++; - ip6stat.ip6s_badscope++; + ip6stat_inc(ip6s_cantforward); + ip6stat_inc(ip6s_badscope); if (ip6_log_time + ip6_log_interval < time_uptime) { ip6_log_time = time_uptime; @@ -316,11 +316,11 @@ reroute: error = ifp->if_output(ifp, m, sin6tosa(dst), rt); if (error) { - ip6stat.ip6s_cantforward++; + ip6stat_inc(ip6s_cantforward); } else { - ip6stat.ip6s_forward++; + ip6stat_inc(ip6s_forward); if (type) - ip6stat.ip6s_redirectsent++; + ip6stat_inc(ip6s_redirectsent); else { if (mcopy) goto freecopy; diff --git a/sys/netinet6/ip6_input.c b/sys/netinet6/ip6_input.c index 5e7949f1065..f1f902107e5 100644 --- a/sys/netinet6/ip6_input.c +++ b/sys/netinet6/ip6_input.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip6_input.c,v 1.175 2017/01/29 19:58:47 bluhm Exp $ */ +/* $OpenBSD: ip6_input.c,v 1.176 2017/02/05 16:04:14 jca Exp $ */ /* $KAME: ip6_input.c,v 1.188 2001/03/29 05:34:31 itojun Exp $ */ /* @@ -117,7 +117,7 @@ struct in6_ifaddrhead in6_ifaddr; struct niqueue ip6intrq = NIQUEUE_INITIALIZER(IFQ_MAXLEN, NETISR_IPV6); -struct ip6stat ip6stat; +struct cpumem *ip6counters; int ip6_check_rh0hdr(struct mbuf *, int *); @@ -158,6 +158,8 @@ ip6_init(void) frag6_init(); mq_init(&ip6send_mq, 64, IPL_SOFTNET); + + ip6counters = counters_alloc(ip6s_ncounters, M_COUNTERS); } /* @@ -191,29 +193,11 @@ ip6_input(struct mbuf *m) if (ifp == NULL) goto bad; - if (m->m_flags & M_EXT) { - if (m->m_next) - ip6stat.ip6s_mext2m++; - else - ip6stat.ip6s_mext1++; - } else { - if (m->m_next) { - int ifidx = m->m_pkthdr.ph_ifidx; - if (m->m_flags & M_LOOP) - ifidx = rtable_loindex(m->m_pkthdr.ph_rtableid); - if (ifidx < nitems(ip6stat.ip6s_m2m)) - ip6stat.ip6s_m2m[ifidx]++; - else - ip6stat.ip6s_m2m[0]++; - } else - ip6stat.ip6s_m1++; - } - - ip6stat.ip6s_total++; + ip6stat_inc(ip6s_total); if (m->m_len < sizeof(struct ip6_hdr)) { if ((m = m_pullup(m, sizeof(struct ip6_hdr))) == NULL) { - ip6stat.ip6s_toosmall++; + ip6stat_inc(ip6s_toosmall); if_put(ifp); return; } @@ -222,7 +206,7 @@ ip6_input(struct mbuf *m) ip6 = mtod(m, struct ip6_hdr *); if ((ip6->ip6_vfc & IPV6_VERSION_MASK) != IPV6_VERSION) { - ip6stat.ip6s_badvers++; + ip6stat_inc(ip6s_badvers); goto bad; } @@ -232,7 +216,7 @@ ip6_input(struct mbuf *m) ip6->ip6_dst.s6_addr32)) goto bad; #endif - ip6stat.ip6s_nxthist[ip6->ip6_nxt]++; + ip6stat_inc(ip6s_nxthist + ip6->ip6_nxt); /* * Check against address spoofing/corruption. @@ -242,20 +226,20 @@ ip6_input(struct mbuf *m) /* * XXX: "badscope" is not very suitable for a multicast source. */ - ip6stat.ip6s_badscope++; + ip6stat_inc(ip6s_badscope); goto bad; } if ((IN6_IS_ADDR_LOOPBACK(&ip6->ip6_src) || IN6_IS_ADDR_LOOPBACK(&ip6->ip6_dst)) && (ifp->if_flags & IFF_LOOPBACK) == 0) { - ip6stat.ip6s_badscope++; + ip6stat_inc(ip6s_badscope); goto bad; } /* Drop packets if interface ID portion is already filled. */ if (((IN6_IS_SCOPE_EMBED(&ip6->ip6_src) && ip6->ip6_src.s6_addr16[1]) || (IN6_IS_SCOPE_EMBED(&ip6->ip6_dst) && ip6->ip6_dst.s6_addr16[1])) && (ifp->if_flags & IFF_LOOPBACK) == 0) { - ip6stat.ip6s_badscope++; + ip6stat_inc(ip6s_badscope); goto bad; } if (IN6_IS_ADDR_MC_INTFACELOCAL(&ip6->ip6_dst) && @@ -266,7 +250,7 @@ ip6_input(struct mbuf *m) * because ip6_mloopback() passes the "actual" interface * as the outgoing/incoming interface. */ - ip6stat.ip6s_badscope++; + ip6stat_inc(ip6s_badscope); goto bad; } @@ -284,7 +268,7 @@ ip6_input(struct mbuf *m) */ if (IN6_IS_ADDR_V4MAPPED(&ip6->ip6_src) || IN6_IS_ADDR_V4MAPPED(&ip6->ip6_dst)) { - ip6stat.ip6s_badscope++; + ip6stat_inc(ip6s_badscope); goto bad; } @@ -295,7 +279,7 @@ ip6_input(struct mbuf *m) */ if (IN6_IS_ADDR_V4COMPAT(&ip6->ip6_src) || IN6_IS_ADDR_V4COMPAT(&ip6->ip6_dst)) { - ip6stat.ip6s_badscope++; + ip6stat_inc(ip6s_badscope); goto bad; } @@ -351,7 +335,7 @@ ip6_input(struct mbuf *m) */ if (!(m->m_pkthdr.pf.flags & PF_TAG_PROCESSED) && ip6_check_rh0hdr(m, &off)) { - ip6stat.ip6s_badoptions++; + ip6stat_inc(ip6s_badoptions); icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER, off); /* m is already freed */ if_put(ifp); @@ -408,7 +392,7 @@ ip6_input(struct mbuf *m) * must be discarded, else it may be accepted below. */ if (ip6_mforward(ip6, ifp, m)) { - ip6stat.ip6s_cantforward++; + ip6stat_inc(ip6s_cantforward); goto bad; } @@ -418,9 +402,9 @@ ip6_input(struct mbuf *m) } #endif if (!ours) { - ip6stat.ip6s_notmember++; + ip6stat_inc(ip6s_notmember); if (!IN6_IS_ADDR_MC_LINKLOCAL(&ip6->ip6_dst)) - ip6stat.ip6s_cantforward++; + ip6stat_inc(ip6s_cantforward); goto bad; } goto hbhcheck; @@ -478,7 +462,7 @@ ip6_input(struct mbuf *m) * and we're not a router. */ if (!ip6_forwarding) { - ip6stat.ip6s_cantforward++; + ip6stat_inc(ip6s_cantforward); goto bad; } @@ -512,12 +496,12 @@ ip6_input(struct mbuf *m) /* * Tell launch routine the next header */ - ip6stat.ip6s_delivered++; + ip6stat_inc(ip6s_delivered); nest = 0; while (nxt != IPPROTO_DONE) { if (ip6_hdrnestlimit && (++nest > ip6_hdrnestlimit)) { - ip6stat.ip6s_toomanyhdr++; + ip6stat_inc(ip6s_toomanyhdr); goto bad; } @@ -526,7 +510,7 @@ ip6_input(struct mbuf *m) * more sanity checks in header chain processing. */ if (m->m_pkthdr.len < off) { - ip6stat.ip6s_tooshort++; + ip6stat_inc(ip6s_tooshort); goto bad; } @@ -588,7 +572,7 @@ ip6_hbhchcheck(struct mbuf *m, int *offp, int *nxtp, int *oursp) * contained, ip6_hopopts_input() must set a valid * (non-zero) payload length to the variable plen. */ - ip6stat.ip6s_badoptions++; + ip6stat_inc(ip6s_badoptions); icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER, (caddr_t)&ip6->ip6_plen - (caddr_t)ip6); @@ -597,7 +581,7 @@ ip6_hbhchcheck(struct mbuf *m, int *offp, int *nxtp, int *oursp) IP6_EXTHDR_GET(hbh, struct ip6_hbh *, m, sizeof(struct ip6_hdr), sizeof(struct ip6_hbh)); if (hbh == NULL) { - ip6stat.ip6s_tooshort++; + ip6stat_inc(ip6s_tooshort); return (-1); } *nxtp = hbh->ip6h_nxt; @@ -618,7 +602,7 @@ ip6_hbhchcheck(struct mbuf *m, int *offp, int *nxtp, int *oursp) * Drop packet if shorter than we expect. */ if (m->m_pkthdr.len - sizeof(struct ip6_hdr) < plen) { - ip6stat.ip6s_tooshort++; + ip6stat_inc(ip6s_tooshort); m_freem(m); return (-1); } @@ -721,14 +705,14 @@ ip6_hopopts_input(u_int32_t *plenp, u_int32_t *rtalertp, struct mbuf **mp, IP6_EXTHDR_GET(hbh, struct ip6_hbh *, m, sizeof(struct ip6_hdr), sizeof(struct ip6_hbh)); if (hbh == NULL) { - ip6stat.ip6s_tooshort++; + ip6stat_inc(ip6s_tooshort); return -1; } hbhlen = (hbh->ip6h_len + 1) << 3; IP6_EXTHDR_GET(hbh, struct ip6_hbh *, m, sizeof(struct ip6_hdr), hbhlen); if (hbh == NULL) { - ip6stat.ip6s_tooshort++; + ip6stat_inc(ip6s_tooshort); return -1; } off += hbhlen; @@ -771,7 +755,7 @@ ip6_process_hopopts(struct mbuf *m, u_int8_t *opthead, int hbhlen, break; case IP6OPT_PADN: if (hbhlen < IP6OPT_MINLEN) { - ip6stat.ip6s_toosmall++; + ip6stat_inc(ip6s_toosmall); goto bad; } optlen = *(opt + 1) + 2; @@ -779,7 +763,7 @@ ip6_process_hopopts(struct mbuf *m, u_int8_t *opthead, int hbhlen, case IP6OPT_ROUTER_ALERT: /* XXX may need check for alignment */ if (hbhlen < IP6OPT_RTALERT_LEN) { - ip6stat.ip6s_toosmall++; + ip6stat_inc(ip6s_toosmall); goto bad; } if (*(opt + 1) != IP6OPT_RTALERT_LEN - 2) { @@ -796,7 +780,7 @@ ip6_process_hopopts(struct mbuf *m, u_int8_t *opthead, int hbhlen, case IP6OPT_JUMBO: /* XXX may need check for alignment */ if (hbhlen < IP6OPT_JUMBO_LEN) { - ip6stat.ip6s_toosmall++; + ip6stat_inc(ip6s_toosmall); goto bad; } if (*(opt + 1) != IP6OPT_JUMBO_LEN - 2) { @@ -814,7 +798,7 @@ ip6_process_hopopts(struct mbuf *m, u_int8_t *opthead, int hbhlen, */ ip6 = mtod(m, struct ip6_hdr *); if (ip6->ip6_plen) { - ip6stat.ip6s_badoptions++; + ip6stat_inc(ip6s_badoptions); icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER, erroff + opt - opthead); @@ -838,7 +822,7 @@ ip6_process_hopopts(struct mbuf *m, u_int8_t *opthead, int hbhlen, * there's no explicit mention in specification. */ if (*plenp != 0) { - ip6stat.ip6s_badoptions++; + ip6stat_inc(ip6s_badoptions); icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER, erroff + opt + 2 - opthead); @@ -850,7 +834,7 @@ ip6_process_hopopts(struct mbuf *m, u_int8_t *opthead, int hbhlen, * jumbo payload length must be larger than 65535. */ if (jumboplen <= IPV6_MAXPACKET) { - ip6stat.ip6s_badoptions++; + ip6stat_inc(ip6s_badoptions); icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER, erroff + opt + 2 - opthead); @@ -861,7 +845,7 @@ ip6_process_hopopts(struct mbuf *m, u_int8_t *opthead, int hbhlen, break; default: /* unknown option */ if (hbhlen < IP6OPT_MINLEN) { - ip6stat.ip6s_toosmall++; + ip6stat_inc(ip6s_toosmall); goto bad; } optlen = ip6_unknown_opt(opt, m, @@ -898,11 +882,11 @@ ip6_unknown_opt(u_int8_t *optp, struct mbuf *m, int off) m_freem(m); return (-1); case IP6OPT_TYPE_FORCEICMP: /* send ICMP even if multicasted */ - ip6stat.ip6s_badoptions++; + ip6stat_inc(ip6s_badoptions); icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_OPTION, off); return (-1); case IP6OPT_TYPE_ICMP: /* send ICMP if not multicasted */ - ip6stat.ip6s_badoptions++; + ip6stat_inc(ip6s_badoptions); ip6 = mtod(m, struct ip6_hdr *); if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst) || (m->m_flags & (M_BCAST|M_MCAST))) @@ -1005,14 +989,14 @@ ip6_savecontrol(struct inpcb *in6p, struct mbuf *m, struct mbuf **mp) ext = ip6_pullexthdr(m, sizeof(struct ip6_hdr), ip6->ip6_nxt); if (ext == NULL) { - ip6stat.ip6s_tooshort++; + ip6stat_inc(ip6s_tooshort); return; } hbh = mtod(ext, struct ip6_hbh *); hbhlen = (hbh->ip6h_len + 1) << 3; if (hbhlen != ext->m_len) { m_freem(ext); - ip6stat.ip6s_tooshort++; + ip6stat_inc(ip6s_tooshort); return; } @@ -1065,7 +1049,7 @@ ip6_savecontrol(struct inpcb *in6p, struct mbuf *m, struct mbuf **mp) ext = ip6_pullexthdr(m, off, nxt); if (ext == NULL) { - ip6stat.ip6s_tooshort++; + ip6stat_inc(ip6s_tooshort); return; } ip6e = mtod(ext, struct ip6_ext *); @@ -1075,7 +1059,7 @@ ip6_savecontrol(struct inpcb *in6p, struct mbuf *m, struct mbuf **mp) elen = (ip6e->ip6e_len + 1) << 3; if (elen != ext->m_len) { m_freem(ext); - ip6stat.ip6s_tooshort++; + ip6stat_inc(ip6s_tooshort); return; } @@ -1350,6 +1334,23 @@ u_char inet6ctlerrmap[PRC_NCMDS] = { int *ipv6ctl_vars[IPV6CTL_MAXID] = IPV6CTL_VARS; int +ip6_sysctl_ip6stat(void *oldp, size_t *oldlenp, void *newp) +{ + struct ip6stat *ip6stat; + int ret; + + CTASSERT(sizeof(*ip6stat) == (ip6s_ncounters * sizeof(uint64_t))); + + ip6stat = malloc(sizeof(*ip6stat), M_TEMP, M_WAITOK); + counters_read(ip6counters, (uint64_t *)ip6stat, ip6s_ncounters); + ret = sysctl_rdstruct(oldp, oldlenp, newp, + ip6stat, sizeof(*ip6stat)); + free(ip6stat, M_TEMP, sizeof(*ip6stat)); + + return (ret); +} + +int ip6_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, size_t newlen) { @@ -1369,10 +1370,7 @@ ip6_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, case IPV6CTL_DAD_PENDING: return sysctl_rdint(oldp, oldlenp, newp, ip6_dad_pending); case IPV6CTL_STATS: - if (newp != NULL) - return (EPERM); - return (sysctl_struct(oldp, oldlenp, newp, newlen, - &ip6stat, sizeof(ip6stat))); + return (ip6_sysctl_ip6stat(oldp, oldlenp, newp)); #ifdef MROUTING case IPV6CTL_MRTSTATS: if (newp != NULL) diff --git a/sys/netinet6/ip6_mroute.c b/sys/netinet6/ip6_mroute.c index 0abe20f8094..f767c07e198 100644 --- a/sys/netinet6/ip6_mroute.c +++ b/sys/netinet6/ip6_mroute.c @@ -873,7 +873,7 @@ ip6_mforward(struct ip6_hdr *ip6, struct ifnet *ifp, struct mbuf *m) * (although such packets must normally set 1 to the hop limit field). */ if (IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_src)) { - ip6stat.ip6s_cantforward++; + ip6stat_inc(ip6s_cantforward); if (ip6_log_time + ip6_log_interval < time_uptime) { char src[INET6_ADDRSTRLEN], dst[INET6_ADDRSTRLEN]; @@ -1158,7 +1158,7 @@ ip6_mdq(struct mbuf *m, struct ifnet *ifp, struct mf6c *rt) in6_addr2scopeid(ifp->if_index, &ip6->ip6_src) != in6_addr2scopeid(mif6table[mifi].m6_ifp->if_index, &ip6->ip6_src))) { - ip6stat.ip6s_badscope++; + ip6stat_inc(ip6s_badscope); continue; } diff --git a/sys/netinet6/ip6_output.c b/sys/netinet6/ip6_output.c index 9d35a8a4c5d..3a11852780f 100644 --- a/sys/netinet6/ip6_output.c +++ b/sys/netinet6/ip6_output.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip6_output.c,v 1.223 2017/02/01 20:59:47 dhill Exp $ */ +/* $OpenBSD: ip6_output.c,v 1.224 2017/02/05 16:04:14 jca Exp $ */ /* $KAME: ip6_output.c,v 1.172 2001/03/25 09:55:56 itojun Exp $ */ /* @@ -361,16 +361,16 @@ ip6_output(struct mbuf *m0, struct ip6_pktopts *opt, struct route_in6 *ro, * we explicitly check the address here for safety. */ error = EOPNOTSUPP; - ip6stat.ip6s_badscope++; + ip6stat_inc(ip6s_badscope); goto bad; } if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_src)) { error = EOPNOTSUPP; - ip6stat.ip6s_badscope++; + ip6stat_inc(ip6s_badscope); goto bad; } - ip6stat.ip6s_localout++; + ip6stat_inc(ip6s_localout); /* * Route packet. @@ -455,7 +455,7 @@ reroute: if (ifp == NULL) { rt = in6_selectroute(&dstsock, opt, ro, ro->ro_tableid); if (rt == NULL) { - ip6stat.ip6s_noroute++; + ip6stat_inc(ip6s_noroute); error = EHOSTUNREACH; goto bad; } @@ -484,7 +484,7 @@ reroute: * Confirm that the outgoing interface supports multicast. */ if ((ifp->if_flags & IFF_MULTICAST) == 0) { - ip6stat.ip6s_noroute++; + ip6stat_inc(ip6s_noroute); error = ENETUNREACH; goto bad; } @@ -738,7 +738,7 @@ reroute: m0 = m; error = ip6_fragment(m0, hlen, nextproto, mtu); if (error) - ip6stat.ip6s_odropped++; + ip6stat_inc(ip6s_odropped); } /* @@ -751,7 +751,7 @@ reroute: m0 = m->m_nextpkt; m->m_nextpkt = 0; if (error == 0) { - ip6stat.ip6s_ofragments++; + ip6stat_inc(ip6s_ofragments); error = ifp->if_output(ifp, m, sin6tosa(dst), ro->ro_rt); } else @@ -759,7 +759,7 @@ reroute: } if (error == 0) - ip6stat.ip6s_fragmented++; + ip6stat_inc(ip6s_fragmented); done: if_put(ifp); diff --git a/sys/netinet6/ip6_var.h b/sys/netinet6/ip6_var.h index 11ff0524bd3..24af0456d50 100644 --- a/sys/netinet6/ip6_var.h +++ b/sys/netinet6/ip6_var.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ip6_var.h,v 1.66 2017/02/01 20:59:47 dhill Exp $ */ +/* $OpenBSD: ip6_var.h,v 1.67 2017/02/05 16:04:14 jca Exp $ */ /* $KAME: ip6_var.h,v 1.33 2000/06/11 14:59:20 jinmei Exp $ */ /* @@ -203,6 +203,65 @@ struct ip6stat { }; #ifdef _KERNEL + +#include <sys/percpu.h> + +enum ip6stat_counters { + ip6s_total, + ip6s_tooshort, + ip6s_toosmall, + ip6s_fragments, + ip6s_fragdropped, + ip6s_fragtimeout, + ip6s_fragoverflow, + ip6s_forward, + ip6s_cantforward, + ip6s_redirectsent, + ip6s_delivered, + ip6s_localout, + ip6s_odropped, + ip6s_reassembled, + ip6s_fragmented, + ip6s_ofragments, + ip6s_cantfrag, + ip6s_badoptions, + ip6s_noroute, + ip6s_badvers, + ip6s_rawout, + ip6s_badscope, + ip6s_notmember, + ip6s_nxthist, + ip6s_m1 = ip6s_nxthist + 256, + ip6s_m2m, + ip6s_mext1 = ip6s_m2m + 32, + ip6s_mext2m, + ip6s_nogif, + ip6s_toomanyhdr, + ip6s_sources_none, + ip6s_sources_sameif, + ip6s_sources_otherif = ip6s_sources_sameif + 16, + ip6s_sources_samescope = ip6s_sources_otherif + 16, + ip6s_sources_otherscope = ip6s_sources_samescope + 16, + ip6s_sources_deprecated = ip6s_sources_otherscope + 16, + ip6s_forward_cachehit = ip6s_sources_deprecated + 16, + ip6s_forward_cachemiss, + ip6s_ncounters, +}; + +extern struct cpumem *ip6counters; + +static inline void +ip6stat_inc(enum ip6stat_counters c) +{ + counters_inc(ip6counters, c); +} + +static inline void +ip6stat_add(enum ip6stat_counters c, uint64_t v) +{ + counters_add(ip6counters, c, v); +} + /* flags passed to ip6_output as last parameter */ #define IPV6_UNSPECSRC 0x01 /* allow :: as the source address */ #define IPV6_FORWARDING 0x02 /* most of IPv6 header exists */ @@ -211,7 +270,6 @@ struct ip6stat { extern int ip6_mtudisc_timeout; /* mtu discovery */ extern struct rttimer_queue *icmp6_mtudisc_timeout_q; -extern struct ip6stat ip6stat; /* statistics */ extern int ip6_defhlim; /* default hop limit */ extern int ip6_defmcasthlim; /* default multicast hop limit */ extern int ip6_forwarding; /* act as router? */ diff --git a/sys/netinet6/raw_ip6.c b/sys/netinet6/raw_ip6.c index c9da7afb9ba..fd1dc59b5a6 100644 --- a/sys/netinet6/raw_ip6.c +++ b/sys/netinet6/raw_ip6.c @@ -1,4 +1,4 @@ -/* $OpenBSD: raw_ip6.c,v 1.104 2017/02/01 20:59:47 dhill Exp $ */ +/* $OpenBSD: raw_ip6.c,v 1.105 2017/02/05 16:04:14 jca Exp $ */ /* $KAME: raw_ip6.c,v 1.69 2001/03/04 15:55:44 itojun Exp $ */ /* @@ -211,6 +211,9 @@ rip6_input(struct mbuf **mp, int *offp, int proto) } else sorwakeup(last->inp_socket); } else { + struct counters_ref ref; + uint64_t *counters; + rip6stat.rip6s_nosock++; if (m->m_flags & M_MCAST) rip6stat.rip6s_nosockmcast++; @@ -222,7 +225,9 @@ rip6_input(struct mbuf **mp, int *offp, int proto) ICMP6_PARAMPROB_NEXTHEADER, prvnxtp - mtod(m, u_int8_t *)); } - ip6stat.ip6s_delivered--; + counters = counters_enter(&ref, ip6counters); + counters[ip6s_delivered]--; + counters_leave(&ref, ip6counters); } return IPPROTO_DONE; } diff --git a/sys/netinet6/route6.c b/sys/netinet6/route6.c index e64ad25f3fb..357fe45a78d 100644 --- a/sys/netinet6/route6.c +++ b/sys/netinet6/route6.c @@ -1,4 +1,4 @@ -/* $OpenBSD: route6.c,v 1.19 2014/12/05 15:50:04 mpi Exp $ */ +/* $OpenBSD: route6.c,v 1.20 2017/02/05 16:04:14 jca Exp $ */ /* $KAME: route6.c,v 1.22 2000/12/03 00:54:00 itojun Exp $ */ /* @@ -60,7 +60,7 @@ route6_input(struct mbuf **mp, int *offp, int proto) ip6 = mtod(m, struct ip6_hdr *); IP6_EXTHDR_GET(rh, struct ip6_rthdr *, m, off, sizeof(*rh)); if (rh == NULL) { - ip6stat.ip6s_tooshort++; + ip6stat_inc(ip6s_tooshort); return IPPROTO_DONE; } @@ -77,7 +77,7 @@ route6_input(struct mbuf **mp, int *offp, int proto) rhlen = (rh->ip6r_len + 1) << 3; break; /* Final dst. Just ignore the header. */ } - ip6stat.ip6s_badoptions++; + ip6stat_inc(ip6s_badoptions); icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER, (caddr_t)&rh->ip6r_type - (caddr_t)ip6); return (IPPROTO_DONE); |