Updated diff that addresses Martin's points: - kill IPv6 mbuf stats; don't change the ip6stat structure yet - there are already other fields that are useless - add ip6stat_add()
Keep the M_COUNTERS change separate for now, I can send an updated diff later if needed. Additionally, - stop testing for (newp != NULL) in ip6_sysctl/IPV6CTL_STATS, sysctl_rdstruct in ip6_sysctl_ip6stat already does so for us. I see no harm in returning an error late here. - move ip6_sysctl_ip6stat above ip6_sysctl to get rid of an unneeded decl Index: net/if_bridge.c =================================================================== RCS file: /d/cvs/src/sys/net/if_bridge.c,v retrieving revision 1.293 diff -u -p -r1.293 if_bridge.c --- net/if_bridge.c 24 Jan 2017 10:08:30 -0000 1.293 +++ net/if_bridge.c 31 Jan 2017 10:53:00 -0000 @@ -1692,7 +1692,7 @@ bridge_ip(struct bridge_softc *sc, int d 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 d ip6 = mtod(m, struct ip6_hdr *); if ((ip6->ip6_vfc & IPV6_VERSION_MASK) != IPV6_VERSION) { - ip6stat.ip6s_badvers++; + ip6stat_inc(ip6s_badvers); goto dropit; } Index: net/pf.c =================================================================== RCS file: /d/cvs/src/sys/net/pf.c,v retrieving revision 1.1013 diff -u -p -r1.1013 pf.c --- net/pf.c 30 Jan 2017 17:52:24 -0000 1.1013 +++ net/pf.c 31 Jan 2017 10:53:00 -0000 @@ -5974,7 +5974,7 @@ pf_route6(struct pf_pdesc *pd, struct pf rt = rtalloc(sin6tosa(dst), RT_RESOLVE, rtableid); if (!rtisvalid(rt)) { - ip6stat.ip6s_noroute++; + ip6stat_inc(ip6s_noroute); goto bad; } Index: netinet/ipsec_input.c =================================================================== RCS file: /d/cvs/src/sys/netinet/ipsec_input.c,v retrieving revision 1.141 diff -u -p -r1.141 ipsec_input.c --- netinet/ipsec_input.c 29 Jan 2017 19:58:47 -0000 1.141 +++ netinet/ipsec_input.c 31 Jan 2017 10:53:00 -0000 @@ -985,7 +985,7 @@ ah6_input_cb(struct mbuf *m, int off, in */ 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, in * 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); Index: netinet6/dest6.c =================================================================== RCS file: /d/cvs/src/sys/netinet6/dest6.c,v retrieving revision 1.15 diff -u -p -r1.15 dest6.c --- netinet6/dest6.c 14 Mar 2015 03:38:52 -0000 1.15 +++ netinet6/dest6.c 31 Jan 2017 10:53:00 -0000 @@ -73,7 +73,7 @@ dest6_input(struct mbuf **mp, int *offp, 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; } Index: netinet6/frag6.c =================================================================== RCS file: /d/cvs/src/sys/netinet6/frag6.c,v retrieving revision 1.71 diff -u -p -r1.71 frag6.c --- netinet6/frag6.c 28 Nov 2016 11:12:45 -0000 1.71 +++ netinet6/frag6.c 31 Jan 2017 13:00:14 -0000 @@ -190,7 +190,7 @@ frag6_input(struct mbuf **mp, int *offp, 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, */ 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, 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, 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(); Index: netinet6/icmp6.c =================================================================== RCS file: /d/cvs/src/sys/netinet6/icmp6.c,v retrieving revision 1.197 diff -u -p -r1.197 icmp6.c --- netinet6/icmp6.c 19 Jan 2017 14:49:19 -0000 1.197 +++ netinet6/icmp6.c 31 Jan 2017 10:53:00 -0000 @@ -1124,8 +1124,13 @@ icmp6_rip6_input(struct mbuf **mp, int o } 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; } Index: netinet6/in6.c =================================================================== RCS file: /d/cvs/src/sys/netinet6/in6.c,v retrieving revision 1.196 diff -u -p -r1.196 in6.c --- netinet6/in6.c 21 Dec 2016 12:11:12 -0000 1.196 +++ netinet6/in6.c 31 Jan 2017 10:53:00 -0000 @@ -1839,20 +1839,20 @@ in6_ifawithscope(struct ifnet *oifp, str /* 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); Index: netinet6/ip6_forward.c =================================================================== RCS file: /d/cvs/src/sys/netinet6/ip6_forward.c,v retrieving revision 1.93 diff -u -p -r1.93 ip6_forward.c --- netinet6/ip6_forward.c 3 Oct 2016 12:33:21 -0000 1.93 +++ netinet6/ip6_forward.c 31 Jan 2017 10:53:00 -0000 @@ -103,7 +103,7 @@ ip6_forward(struct mbuf *m, struct rtent 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; Index: netinet6/ip6_input.c =================================================================== RCS file: /d/cvs/src/sys/netinet6/ip6_input.c,v retrieving revision 1.175 diff -u -p -r1.175 ip6_input.c --- netinet6/ip6_input.c 29 Jan 2017 19:58:47 -0000 1.175 +++ netinet6/ip6_input.c 31 Jan 2017 13:07:54 -0000 @@ -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 * 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 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 * 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_in 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_in 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_in 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_in 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_in */ 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_in * 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_in * 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_in 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 m 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, stru 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, stru 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, stru 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, voi 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) Index: netinet6/ip6_mroute.c =================================================================== RCS file: /d/cvs/src/sys/netinet6/ip6_mroute.c,v retrieving revision 1.107 diff -u -p -r1.107 ip6_mroute.c --- netinet6/ip6_mroute.c 6 Jan 2017 10:02:57 -0000 1.107 +++ netinet6/ip6_mroute.c 31 Jan 2017 10:53:00 -0000 @@ -875,7 +875,7 @@ ip6_mforward(struct ip6_hdr *ip6, struct * (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]; @@ -1160,7 +1160,7 @@ ip6_mdq(struct mbuf *m, struct ifnet *if 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; } Index: netinet6/ip6_output.c =================================================================== RCS file: /d/cvs/src/sys/netinet6/ip6_output.c,v retrieving revision 1.222 diff -u -p -r1.222 ip6_output.c --- netinet6/ip6_output.c 27 Jan 2017 02:55:36 -0000 1.222 +++ netinet6/ip6_output.c 31 Jan 2017 10:53:00 -0000 @@ -361,16 +361,16 @@ ip6_output(struct mbuf *m0, struct ip6_p * 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); Index: netinet6/ip6_var.h =================================================================== RCS file: /d/cvs/src/sys/netinet6/ip6_var.h,v retrieving revision 1.65 diff -u -p -r1.65 ip6_var.h --- netinet6/ip6_var.h 2 Dec 2016 11:16:04 -0000 1.65 +++ netinet6/ip6_var.h 31 Jan 2017 12:39:46 -0000 @@ -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? */ Index: netinet6/raw_ip6.c =================================================================== RCS file: /d/cvs/src/sys/netinet6/raw_ip6.c,v retrieving revision 1.103 diff -u -p -r1.103 raw_ip6.c --- netinet6/raw_ip6.c 23 Jan 2017 16:31:24 -0000 1.103 +++ netinet6/raw_ip6.c 31 Jan 2017 10:53:00 -0000 @@ -211,6 +211,9 @@ rip6_input(struct mbuf **mp, int *offp, } 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, 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; } Index: netinet6/route6.c =================================================================== RCS file: /d/cvs/src/sys/netinet6/route6.c,v retrieving revision 1.19 diff -u -p -r1.19 route6.c --- netinet6/route6.c 5 Dec 2014 15:50:04 -0000 1.19 +++ netinet6/route6.c 31 Jan 2017 10:53:00 -0000 @@ -60,7 +60,7 @@ route6_input(struct mbuf **mp, int *offp 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 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); -- jca | PGP : 0x1524E7EE / 5135 92C1 AD36 5293 2BDF DDCC 0DFA 74AE 1524 E7EE