Index: net/if_bridge.c =================================================================== RCS file: /cvs/src/sys/net/if_bridge.c,v retrieving revision 1.287 diff -u -p -r1.287 if_bridge.c --- net/if_bridge.c 3 Oct 2016 15:53:09 -0000 1.287 +++ net/if_bridge.c 9 Nov 2016 04:45:23 -0000 @@ -1603,25 +1603,25 @@ bridge_ip(struct bridge_softc *sc, int d /* Copy minimal header, and drop invalids */ if (m->m_len < sizeof(struct ip) && (m = m_pullup(m, sizeof(struct ip))) == NULL) { - ipstat.ips_toosmall++; + ipstat_inc(ips_toosmall); return (NULL); } ip = mtod(m, struct ip *); if (ip->ip_v != IPVERSION) { - ipstat.ips_badvers++; + ipstat_inc(ips_badvers); goto dropit; } hlen = ip->ip_hl << 2; /* get whole header length */ if (hlen < sizeof(struct ip)) { - ipstat.ips_badhlen++; + ipstat_inc(ips_badhlen); goto dropit; } if (hlen > m->m_len) { if ((m = m_pullup(m, hlen)) == NULL) { - ipstat.ips_badhlen++; + ipstat_inc(ips_badhlen); return (NULL); } ip = mtod(m, struct ip *); @@ -1629,13 +1629,13 @@ bridge_ip(struct bridge_softc *sc, int d if ((m->m_pkthdr.csum_flags & M_IPV4_CSUM_IN_OK) == 0) { if (m->m_pkthdr.csum_flags & M_IPV4_CSUM_IN_BAD) { - ipstat.ips_badsum++; + ipstat_inc(ips_badsum); goto dropit; } - ipstat.ips_inswcsum++; + ipstat_inc(ips_inswcsum); if (in_cksum(m, hlen) != 0) { - ipstat.ips_badsum++; + ipstat_inc(ips_badsum); goto dropit; } } @@ -1678,7 +1678,7 @@ bridge_ip(struct bridge_softc *sc, int d if (0 && (ifp->if_capabilities & IFCAP_CSUM_IPv4)) m->m_pkthdr.csum_flags |= M_IPV4_CSUM_OUT; else { - ipstat.ips_outswcsum++; + ipstat_inc(ips_outswcsum); ip->ip_sum = in_cksum(m, hlen); } @@ -1848,7 +1848,7 @@ bridge_fragment(struct bridge_softc *sc, } if (error == 0) - ipstat.ips_fragmented++; + ipstat_inc(ips_fragmented); return; dropit: Index: net/if_etherip.c =================================================================== RCS file: /cvs/src/sys/net/if_etherip.c,v retrieving revision 1.7 diff -u -p -r1.7 if_etherip.c --- net/if_etherip.c 13 Apr 2016 11:41:15 -0000 1.7 +++ net/if_etherip.c 9 Nov 2016 04:45:23 -0000 @@ -430,7 +430,7 @@ ip_etherip_input(struct mbuf *m, ...) if (ip->ip_p != IPPROTO_ETHERIP) { m_freem(m); - ipstat.ips_noproto++; + ipstat_inc(ips_noproto); return; } Index: net/pf.c =================================================================== RCS file: /cvs/src/sys/net/pf.c,v retrieving revision 1.996 diff -u -p -r1.996 pf.c --- net/pf.c 28 Oct 2016 07:54:19 -0000 1.996 +++ net/pf.c 9 Nov 2016 04:45:23 -0000 @@ -5825,7 +5825,7 @@ pf_route(struct mbuf **m, struct pf_pdes if (!r->rt) { rt = rtalloc(sintosa(dst), RT_RESOLVE, rtableid); if (rt == NULL) { - ipstat.ips_noroute++; + ipstat_inc(ips_noroute); goto bad; } @@ -5859,7 +5859,7 @@ pf_route(struct mbuf **m, struct pf_pdes rt = rtalloc(sintosa(dst), RT_RESOLVE, rtableid); if (rt == NULL) { - ipstat.ips_noroute++; + ipstat_inc(ips_noroute); goto bad; } } @@ -5887,7 +5887,7 @@ pf_route(struct mbuf **m, struct pf_pdes if (ifp->if_capabilities & IFCAP_CSUM_IPv4) m0->m_pkthdr.csum_flags |= M_IPV4_CSUM_OUT; else { - ipstat.ips_outswcsum++; + ipstat_inc(ips_outswcsum); ip->ip_sum = in_cksum(m0, ip->ip_hl << 2); } error = ifp->if_output(ifp, m0, sintosa(dst), rt); @@ -5899,7 +5899,7 @@ pf_route(struct mbuf **m, struct pf_pdes * Must be able to put at least 8 bytes per fragment. */ if (ip->ip_off & htons(IP_DF)) { - ipstat.ips_cantfrag++; + ipstat_inc(ips_cantfrag); if (r->rt != PF_DUPTO) { icmp_error(m0, ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG, 0, ifp->if_mtu); @@ -5925,7 +5925,7 @@ pf_route(struct mbuf **m, struct pf_pdes } if (error == 0) - ipstat.ips_fragmented++; + ipstat_inc(ips_fragmented); done: if (r->rt != PF_DUPTO) Index: netinet/ip_icmp.c =================================================================== RCS file: /cvs/src/sys/netinet/ip_icmp.c,v retrieving revision 1.152 diff -u -p -r1.152 ip_icmp.c --- netinet/ip_icmp.c 22 Aug 2016 15:37:23 -0000 1.152 +++ netinet/ip_icmp.c 9 Nov 2016 04:45:23 -0000 @@ -751,7 +751,7 @@ icmp_reflect(struct mbuf *m, struct mbuf /* keep packet in the original virtual instance */ rt = rtalloc(sintosa(&sin), RT_RESOLVE, rtableid); if (rt == NULL) { - ipstat.ips_noroute++; + ipstat_inc(ips_noroute); m_freem(m); return (EHOSTUNREACH); } Index: netinet/ip_input.c =================================================================== RCS file: /cvs/src/sys/netinet/ip_input.c,v retrieving revision 1.282 diff -u -p -r1.282 ip_input.c --- netinet/ip_input.c 22 Sep 2016 10:12:25 -0000 1.282 +++ netinet/ip_input.c 9 Nov 2016 04:45:23 -0000 @@ -120,7 +120,9 @@ struct niqueue ipintrq = NIQUEUE_INITIAL struct pool ipqent_pool; struct pool ipq_pool; -struct ipstat ipstat; +struct cpumem *ipcounters; + +int ip_sysctl_ipstat(void *, size_t *, void *); static struct mbuf_queue ipsend_mq; @@ -132,7 +134,7 @@ void ip_forward(struct mbuf *, struct if int ip_input_ipsec_fwd_check(struct mbuf *, int); int ip_input_ipsec_ours_check(struct mbuf *, int); #endif /* IPSEC */ - + static void ip_send_dispatch(void *); static struct task ipsend_task = TASK_INITIALIZER(ip_send_dispatch, &ipsend_mq); /* @@ -166,6 +168,8 @@ ip_init(void) const u_int16_t defrootonlyports_tcp[] = DEFROOTONLYPORTS_TCP; const u_int16_t defrootonlyports_udp[] = DEFROOTONLYPORTS_UDP; + ipcounters = counters_alloc(ips_ncounters, M_PCB); + pool_init(&ipqent_pool, sizeof(struct ipqent), 0, IPL_SOFTNET, 0, "ipqe", NULL); pool_init(&ipq_pool, sizeof(struct ipq), 0, @@ -247,25 +251,25 @@ ipv4_input(struct mbuf *m) if (ifp == NULL) goto bad; - ipstat.ips_total++; + ipstat_inc(ips_total); if (m->m_len < sizeof (struct ip) && (m = m_pullup(m, sizeof (struct ip))) == NULL) { - ipstat.ips_toosmall++; + ipstat_inc(ips_toosmall); goto out; } ip = mtod(m, struct ip *); if (ip->ip_v != IPVERSION) { - ipstat.ips_badvers++; + ipstat_inc(ips_badvers); goto bad; } hlen = ip->ip_hl << 2; if (hlen < sizeof(struct ip)) { /* minimum header length */ - ipstat.ips_badhlen++; + ipstat_inc(ips_badhlen); goto bad; } if (hlen > m->m_len) { if ((m = m_pullup(m, hlen)) == NULL) { - ipstat.ips_badhlen++; + ipstat_inc(ips_badhlen); goto out; } ip = mtod(m, struct ip *); @@ -275,20 +279,20 @@ ipv4_input(struct mbuf *m) if ((ntohl(ip->ip_dst.s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET || (ntohl(ip->ip_src.s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET) { if ((ifp->if_flags & IFF_LOOPBACK) == 0) { - ipstat.ips_badaddr++; + ipstat_inc(ips_badaddr); goto bad; } } if ((m->m_pkthdr.csum_flags & M_IPV4_CSUM_IN_OK) == 0) { if (m->m_pkthdr.csum_flags & M_IPV4_CSUM_IN_BAD) { - ipstat.ips_badsum++; + ipstat_inc(ips_badsum); goto bad; } - ipstat.ips_inswcsum++; + ipstat_inc(ips_inswcsum); if (in_cksum(m, hlen) != 0) { - ipstat.ips_badsum++; + ipstat_inc(ips_badsum); goto bad; } } @@ -300,7 +304,7 @@ ipv4_input(struct mbuf *m) * Convert fields to host representation. */ if (len < hlen) { - ipstat.ips_badlen++; + ipstat_inc(ips_badlen); goto bad; } @@ -311,7 +315,7 @@ ipv4_input(struct mbuf *m) * Drop packet if shorter than we expect. */ if (m->m_pkthdr.len < len) { - ipstat.ips_tooshort++; + ipstat_inc(ips_tooshort); goto bad; } if (m->m_pkthdr.len > len) { @@ -370,7 +374,7 @@ ipv4_input(struct mbuf *m) if (ipmforwarding && ip_mrouter) { if (m->m_flags & M_EXT) { if ((m = m_pullup(m, hlen)) == NULL) { - ipstat.ips_toosmall++; + ipstat_inc(ips_toosmall); goto out; } ip = mtod(m, struct ip *); @@ -391,7 +395,7 @@ ipv4_input(struct mbuf *m) rv = ip_mforward(m, ifp); KERNEL_UNLOCK(); if (rv != 0) { - ipstat.ips_cantforward++; + ipstat_inc(ips_cantforward); goto bad; } @@ -404,7 +408,7 @@ ipv4_input(struct mbuf *m) ip_ours(m); goto out; } - ipstat.ips_forward++; + ipstat_inc(ips_forward); } #endif /* @@ -412,9 +416,9 @@ ipv4_input(struct mbuf *m) * arrival interface. */ if (!in_hasmulti(&ip->ip_dst, ifp)) { - ipstat.ips_notmember++; + ipstat_inc(ips_notmember); if (!IN_LOCAL_GROUP(ip->ip_dst.s_addr)) - ipstat.ips_cantforward++; + ipstat_inc(ips_cantforward); goto bad; } ip_ours(m); @@ -436,7 +440,7 @@ ipv4_input(struct mbuf *m) * Not for us; forward if possible and desirable. */ if (ipforwarding == 0) { - ipstat.ips_cantforward++; + ipstat_inc(ips_cantforward); goto bad; } #ifdef IPSEC @@ -445,7 +449,7 @@ ipv4_input(struct mbuf *m) rv = ip_input_ipsec_fwd_check(m, hlen); KERNEL_UNLOCK(); if (rv != 0) { - ipstat.ips_cantforward++; + ipstat_inc(ips_cantforward); goto bad; } /* @@ -493,7 +497,7 @@ ip_ours(struct mbuf *m) if (ip->ip_off &~ htons(IP_DF | IP_RF)) { if (m->m_flags & M_EXT) { /* XXX */ if ((m = m_pullup(m, hlen)) == NULL) { - ipstat.ips_toosmall++; + ipstat_inc(ips_toosmall); return; } ip = mtod(m, struct ip *); @@ -526,7 +530,7 @@ found: */ if (ntohs(ip->ip_len) == 0 || (ntohs(ip->ip_len) & 0x7) != 0) { - ipstat.ips_badfrags++; + ipstat_inc(ips_badfrags); goto bad; } } @@ -538,16 +542,16 @@ found: * attempt reassembly; if it succeeds, proceed. */ if (mff || ip->ip_off) { - ipstat.ips_fragments++; + ipstat_inc(ips_fragments); if (ip_frags + 1 > ip_maxqueue) { ip_flush(); - ipstat.ips_rcvmemdrop++; + ipstat_inc(ips_rcvmemdrop); goto bad; } ipqe = pool_get(&ipqent_pool, PR_NOWAIT); if (ipqe == NULL) { - ipstat.ips_rcvmemdrop++; + ipstat_inc(ips_rcvmemdrop); goto bad; } ip_frags++; @@ -558,7 +562,7 @@ found: if (m == NULL) { return; } - ipstat.ips_reassembled++; + ipstat_inc(ips_reassembled); ip = mtod(m, struct ip *); hlen = ip->ip_hl << 2; ip->ip_len = htons(ntohs(ip->ip_len) + hlen); @@ -570,7 +574,7 @@ found: #ifdef IPSEC if (ipsec_in_use) { if (ip_input_ipsec_ours_check(m, hlen) != 0) { - ipstat.ips_cantforward++; + ipstat_inc(ips_cantforward); goto bad; } } @@ -580,7 +584,7 @@ found: /* * Switch out to protocol's input routine. */ - ipstat.ips_delivered++; + ipstat_inc(ips_delivered); (*inetsw[ip_protox[ip->ip_p]].pr_input)(m, hlen, NULL, 0); return; bad: @@ -896,7 +900,7 @@ insert: q = LIST_FIRST(&fp->ipq_fragq); ip = q->ipqe_ip; if ((next + (ip->ip_hl << 2)) > IP_MAXPACKET) { - ipstat.ips_toolong++; + ipstat_inc(ips_toolong); ip_freef(fp); return (0); } @@ -938,7 +942,7 @@ insert: return (m); dropfrag: - ipstat.ips_fragdropped++; + ipstat_inc(ips_fragdropped); m_freem(m); pool_put(&ipqent_pool, ipqe); ip_frags--; @@ -979,7 +983,7 @@ ip_slowtimo(void) for (fp = LIST_FIRST(&ipq); fp != NULL; fp = nfp) { nfp = LIST_NEXT(fp, ipq_q); if (--fp->ipq_ttl == 0) { - ipstat.ips_fragtimeout++; + ipstat_inc(ips_fragtimeout); ip_freef(fp); } } @@ -993,7 +997,7 @@ void ip_drain(void) { while (!LIST_EMPTY(&ipq)) { - ipstat.ips_fragdropped++; + ipstat_inc(ips_fragdropped); ip_freef(LIST_FIRST(&ipq)); } } @@ -1008,7 +1012,7 @@ ip_flush(void) /* ipq already locked */ while (!LIST_EMPTY(&ipq) && ip_frags > ip_maxqueue * 3 / 4 && --max) { - ipstat.ips_fragdropped++; + ipstat_inc(ips_fragdropped); ip_freef(LIST_FIRST(&ipq)); } } @@ -1263,7 +1267,7 @@ ip_dooptions(struct mbuf *m, struct ifne bad: KERNEL_UNLOCK(); icmp_error(m, type, code, 0, 0); - ipstat.ips_badoptions++; + ipstat_inc(ips_badoptions); return (1); } @@ -1413,7 +1417,7 @@ ip_forward(struct mbuf *m, struct ifnet dest = 0; if (m->m_flags & (M_BCAST|M_MCAST) || in_canforward(ip->ip_dst) == 0) { - ipstat.ips_cantforward++; + ipstat_inc(ips_cantforward); m_freem(m); goto freecopy; } @@ -1494,11 +1498,11 @@ ip_forward(struct mbuf *m, struct ifnet NULL, NULL, 0); rt = ro.ro_rt; if (error) - ipstat.ips_cantforward++; + ipstat_inc(ips_cantforward); else { - ipstat.ips_forward++; + ipstat_inc(ips_forward); if (type) - ipstat.ips_redirectsent++; + ipstat_inc(ips_redirectsent); else goto freecopy; } @@ -1538,7 +1542,7 @@ ip_forward(struct mbuf *m, struct ifnet } } #endif /*IPSEC*/ - ipstat.ips_cantfrag++; + ipstat_inc(ips_cantfrag); break; case EACCES: @@ -1632,8 +1636,7 @@ ip_sysctl(int *name, u_int namelen, void return (sysctl_niq(name + 1, namelen - 1, oldp, oldlenp, newp, newlen, &ipintrq)); case IPCTL_STATS: - return (sysctl_rdstruct(oldp, oldlenp, newp, - &ipstat, sizeof(ipstat))); + return (ip_sysctl_ipstat(oldp, oldlenp, newp)); #ifdef MROUTING case IPCTL_MRTSTATS: return (sysctl_rdstruct(oldp, oldlenp, newp, @@ -1662,6 +1665,24 @@ ip_sysctl(int *name, u_int namelen, void return (EOPNOTSUPP); } /* NOTREACHED */ +} + +int +ip_sysctl_ipstat(void *oldp, size_t *oldlenp, void *newp) +{ + uint64_t counters[ips_ncounters]; + struct ipstat ipstat; + u_long *words = (u_long *)&ipstat; + int i; + + KASSERT(sizeof(ipstat) == (nitems(counters) * sizeof(u_long))); + + counters_read(ipcounters, counters, nitems(counters)); + + for (i = 0; i < nitems(counters); i++) + words[i] = (u_long)counters[i]; + + return (sysctl_rdstruct(oldp, oldlenp, newp, &ipstat, sizeof(ipstat))); } void Index: netinet/ip_output.c =================================================================== RCS file: /cvs/src/sys/netinet/ip_output.c,v retrieving revision 1.327 diff -u -p -r1.327 ip_output.c --- netinet/ip_output.c 4 Sep 2016 17:18:56 -0000 1.327 +++ netinet/ip_output.c 9 Nov 2016 04:45:23 -0000 @@ -133,7 +133,7 @@ ip_output(struct mbuf *m0, struct mbuf * ip->ip_off &= htons(IP_DF); ip->ip_id = htons(ip_randomid()); ip->ip_hl = hlen >> 2; - ipstat.ips_localout++; + ipstat_inc(ips_localout); } else { hlen = ip->ip_hl << 2; } @@ -204,7 +204,7 @@ reroute: &ip->ip_src.s_addr, ro->ro_tableid); if (ro->ro_rt == NULL) { - ipstat.ips_noroute++; + ipstat_inc(ips_noroute); error = EHOSTUNREACH; goto bad; } @@ -284,7 +284,7 @@ reroute: * output */ if (!ifp) { - ipstat.ips_noroute++; + ipstat_inc(ips_noroute); error = EHOSTUNREACH; goto bad; } @@ -298,7 +298,7 @@ reroute: (ifp->if_flags & IFF_MULTICAST) == 0) || ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_BROADCAST) == 0)) && (tdb == NULL)) { - ipstat.ips_noroute++; + ipstat_inc(ips_noroute); error = ENETUNREACH; goto bad; } @@ -464,7 +464,7 @@ sendit: (ifp->if_bridgeport == NULL)) m->m_pkthdr.csum_flags |= M_IPV4_CSUM_OUT; else { - ipstat.ips_outswcsum++; + ipstat_inc(ips_outswcsum); ip->ip_sum = in_cksum(m, hlen); } @@ -495,7 +495,7 @@ sendit: (ro->ro_rt->rt_rmx.rmx_mtu > ifp->if_mtu)) { ro->ro_rt->rt_rmx.rmx_mtu = ifp->if_mtu; } - ipstat.ips_cantfrag++; + ipstat_inc(ips_cantfrag); goto bad; } @@ -515,7 +515,7 @@ sendit: } if (error == 0) - ipstat.ips_fragmented++; + ipstat_inc(ips_fragmented); done: if (ro == &iproute && ro->ro_rt) @@ -676,7 +676,7 @@ ip_fragment(struct mbuf *m, struct ifnet for (off = hlen + len; off < ntohs(ip->ip_len); off += len) { MGETHDR(m, M_DONTWAIT, MT_HEADER); if (m == NULL) { - ipstat.ips_odropped++; + ipstat_inc(ips_odropped); error = ENOBUFS; goto sendorfree; } @@ -705,7 +705,7 @@ ip_fragment(struct mbuf *m, struct ifnet mhip->ip_len = htons((u_int16_t)(len + mhlen)); m->m_next = m_copym(m0, off, len, M_NOWAIT); if (m->m_next == 0) { - ipstat.ips_odropped++; + ipstat_inc(ips_odropped); error = ENOBUFS; goto sendorfree; } @@ -718,10 +718,10 @@ ip_fragment(struct mbuf *m, struct ifnet (ifp->if_bridgeport == NULL)) m->m_pkthdr.csum_flags |= M_IPV4_CSUM_OUT; else { - ipstat.ips_outswcsum++; + ipstat_inc(ips_outswcsum); mhip->ip_sum = in_cksum(m, mhlen); } - ipstat.ips_ofragments++; + ipstat_inc(ips_ofragments); fragments++; } /* @@ -739,7 +739,7 @@ ip_fragment(struct mbuf *m, struct ifnet (ifp->if_bridgeport == NULL)) m->m_pkthdr.csum_flags |= M_IPV4_CSUM_OUT; else { - ipstat.ips_outswcsum++; + ipstat_inc(ips_outswcsum); ip->ip_sum = in_cksum(m, hlen); } sendorfree: Index: netinet/ip_var.h =================================================================== RCS file: /cvs/src/sys/netinet/ip_var.h,v retrieving revision 1.62 diff -u -p -r1.62 ip_var.h --- netinet/ip_var.h 15 Apr 2016 11:18:40 -0000 1.62 +++ netinet/ip_var.h 9 Nov 2016 04:45:23 -0000 @@ -96,6 +96,53 @@ struct ipoption { #ifdef _KERNEL +#include + +enum ipstat_counters { + ips_total, /* total packets received */ + ips_badsum, /* checksum bad */ + ips_tooshort, /* packet too short */ + ips_toosmall, /* not enough data */ + ips_badhlen, /* ip header length < data size */ + ips_badlen, /* ip length < ip header length */ + ips_fragments, /* fragments received */ + ips_fragdropped, /* frags dropped (dups, out of space) */ + ips_fragtimeout, /* fragments timed out */ + ips_forward, /* packets forwarded */ + ips_cantforward, /* packets rcvd for unreachable dest */ + ips_redirectsent, /* packets forwarded on same net */ + ips_noproto, /* unknown or unsupported protocol */ + ips_delivered, /* datagrams delivered to upper level*/ + ips_localout, /* total ip packets generated here */ + ips_odropped, /* lost packets due to nobufs, etc. */ + ips_reassembled, /* total packets reassembled ok */ + ips_fragmented, /* datagrams successfully fragmented */ + ips_ofragments, /* output fragments created */ + ips_cantfrag, /* don't fragment flag was set, etc. */ + ips_badoptions, /* error in option processing */ + ips_noroute, /* packets discarded due to no route */ + ips_badvers, /* ip version != 4 */ + ips_rawout, /* total raw ip packets generated */ + ips_badfrags, /* malformed fragments (bad length) */ + ips_rcvmemdrop, /* frags dropped for lack of memory */ + ips_toolong, /* ip length > max ip packet size */ + ips_nogif, /* no match gif found */ + ips_badaddr, /* invalid address on header */ + ips_inswcsum, /* software checksummed on input */ + ips_outswcsum, /* software checksummed on output */ + ips_notmember, /* multicasts for unregistered groups */ + + ips_ncounters +}; + +extern struct cpumem *ipcounters; + +static inline void +ipstat_inc(enum ipstat_counters c) +{ + counters_inc(ipcounters, c); +} + /* * Structure attached to inpcb.ip_moptions and * passed to ip_output when IP multicast options are in use. Index: netinet/raw_ip.c =================================================================== RCS file: /cvs/src/sys/netinet/raw_ip.c,v retrieving revision 1.86 diff -u -p -r1.86 raw_ip.c --- netinet/raw_ip.c 7 Mar 2016 18:44:00 -0000 1.86 +++ netinet/raw_ip.c 9 Nov 2016 04:45:23 -0000 @@ -126,6 +126,8 @@ rip_input(struct mbuf *m, ...) struct ip *ip = mtod(m, struct ip *); struct inpcb *inp, *last = NULL; struct mbuf *opts = NULL; + struct counters_ref ref; + uint64_t *counters; ripsrc.sin_addr = ip->ip_src; TAILQ_FOREACH(inp, &rawcbtable.inpt_queue, inp_queue) { @@ -195,8 +197,11 @@ rip_input(struct mbuf *m, ...) icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_PROTOCOL, 0, 0); else m_freem(m); - ipstat.ips_noproto++; - ipstat.ips_delivered--; + + counters = counters_enter(&ref, ipcounters); + counters[ips_noproto]++; + counters[ips_delivered]--; + counters_leave(&ref, ipcounters); } } @@ -267,7 +272,7 @@ rip_output(struct mbuf *m, ...) } /* XXX prevent ip_output from overwriting header fields */ flags |= IP_RAWOUTPUT; - ipstat.ips_rawout++; + ipstat_inc(ips_rawout); } #ifdef INET6 /* Index: sys/percpu.h =================================================================== RCS file: /cvs/src/sys/sys/percpu.h,v retrieving revision 1.3 diff -u -p -r1.3 percpu.h --- sys/percpu.h 24 Oct 2016 23:58:33 -0000 1.3 +++ sys/percpu.h 9 Nov 2016 04:45:23 -0000 @@ -138,6 +138,40 @@ counters_leave(struct counters_ref *ref, cpumem_leave(cm, ref->c); } +static inline void +counters_inc(struct cpumem *cm, unsigned int c) +{ + struct counters_ref ref; + uint64_t *counters; + + counters = counters_enter(&ref, cm); + counters[c]++; + counters_leave(&ref, cm); +} + +static inline void +counters_add(struct cpumem *cm, unsigned int c, uint64_t v) +{ + struct counters_ref ref; + uint64_t *counters; + + counters = counters_enter(&ref, cm); + counters[c] += v; + counters_leave(&ref, cm); +} + +static inline void +counters_pkt(struct cpumem *cm, unsigned int c, unsigned int b, uint64_t v) +{ + struct counters_ref ref; + uint64_t *counters; + + counters = counters_enter(&ref, cm); + counters[c]++; + counters[b] += v; + counters_leave(&ref, cm); +} + #ifdef MULTIPROCESSOR #define COUNTERS_BOOT_MEMORY(_name, _n) \ CPUMEM_BOOT_MEMORY(_name, ((_n) + 1) * sizeof(uint64_t))