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

Reply via email to