On Tue, Jan 31, 2017 at 02:21:46PM +0100, Jeremie Courreges-Anglas wrote: > > 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
OK bluhm@ > > > 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