its as close to the ipstat change as i can make it.

ok?

Index: net/pipex.c
===================================================================
RCS file: /cvs/src/sys/net/pipex.c,v
retrieving revision 1.89
diff -u -p -r1.89 pipex.c
--- net/pipex.c 15 Sep 2016 02:00:18 -0000      1.89
+++ net/pipex.c 14 Nov 2016 04:27:42 -0000
@@ -1986,7 +1986,7 @@ pipex_l2tp_output(struct mbuf *m0, struc
                break;
 #endif
        }
-       udpstat.udps_opackets++;
+       udpstat_inc(udps_opackets);
 
        if (datalen > 0) {      /* network layer only */
                /* countup statistics */
Index: netinet/ip_output.c
===================================================================
RCS file: /cvs/src/sys/netinet/ip_output.c,v
retrieving revision 1.328
diff -u -p -r1.328 ip_output.c
--- netinet/ip_output.c 14 Nov 2016 03:51:53 -0000      1.328
+++ netinet/ip_output.c 14 Nov 2016 04:27:42 -0000
@@ -1811,7 +1811,7 @@ in_proto_cksum_out(struct mbuf *m, struc
        } else if (m->m_pkthdr.csum_flags & M_UDP_CSUM_OUT) {
                if (!ifp || !(ifp->if_capabilities & IFCAP_CSUM_UDPv4) ||
                    ip->ip_hl != 5 || ifp->if_bridgeport != NULL) {
-                       udpstat.udps_outswcsum++;
+                       udpstat_inc(udps_outswcsum);
                        in_delayed_cksum(m);
                        m->m_pkthdr.csum_flags &= ~M_UDP_CSUM_OUT; /* Clear */
                }
Index: netinet/udp_usrreq.c
===================================================================
RCS file: /cvs/src/sys/netinet/udp_usrreq.c,v
retrieving revision 1.220
diff -u -p -r1.220 udp_usrreq.c
--- netinet/udp_usrreq.c        3 Nov 2016 18:42:35 -0000       1.220
+++ netinet/udp_usrreq.c        14 Nov 2016 04:27:42 -0000
@@ -130,10 +130,11 @@ u_int     udp_recvspace = 40 * (1024 + sizeo
 int *udpctl_vars[UDPCTL_MAXID] = UDPCTL_VARS;
 
 struct inpcbtable udbtable;
-struct udpstat udpstat;
+struct cpumem *udpcounters;
 
 int    udp_output(struct inpcb *, struct mbuf *, struct mbuf *, struct mbuf *);
 void   udp_notify(struct inpcb *, int);
+int    udp_sysctl_udpstat(void *, size_t *, void *);
 
 #ifndef        UDB_INITIAL_HASH_SIZE
 #define        UDB_INITIAL_HASH_SIZE   128
@@ -142,6 +143,7 @@ void        udp_notify(struct inpcb *, int);
 void
 udp_init(void)
 {
+       udpcounters = counters_alloc(udps_ncounters, M_COUNTERS);
        in_pcbinit(&udbtable, UDB_INITIAL_HASH_SIZE);
 }
 
@@ -189,7 +191,7 @@ udp_input(struct mbuf *m, ...)
        iphlen = va_arg(ap, int);
        va_end(ap);
 
-       udpstat.udps_ipackets++;
+       udpstat_inc(udps_ipackets);
 
        switch (mtod(m, struct ip *)->ip_v) {
        case 4:
@@ -212,13 +214,13 @@ udp_input(struct mbuf *m, ...)
 
        IP6_EXTHDR_GET(uh, struct udphdr *, m, iphlen, sizeof(struct udphdr));
        if (!uh) {
-               udpstat.udps_hdrops++;
+               udpstat_inc(udps_hdrops);
                return;
        }
 
        /* Check for illegal destination port 0 */
        if (uh->uh_dport == 0) {
-               udpstat.udps_noport++;
+               udpstat_inc(udps_noport);
                goto bad;
        }
 
@@ -231,7 +233,7 @@ udp_input(struct mbuf *m, ...)
                if (m->m_pkthdr.len - iphlen != len) {
                        if (len > (m->m_pkthdr.len - iphlen) ||
                            len < sizeof(struct udphdr)) {
-                               udpstat.udps_badlen++;
+                               udpstat_inc(udps_badlen);
                                goto bad;
                        }
                        m_adj(m, len - (m->m_pkthdr.len - iphlen));
@@ -243,7 +245,7 @@ udp_input(struct mbuf *m, ...)
                if (len == 0 && m->m_pkthdr.len - iphlen > 0xffff)
                        len = m->m_pkthdr.len - iphlen;
                if (len != m->m_pkthdr.len - iphlen) {
-                       udpstat.udps_badlen++;
+                       udpstat_inc(udps_badlen);
                        goto bad;
                }
        }
@@ -276,7 +278,7 @@ udp_input(struct mbuf *m, ...)
         */
        savesum = uh->uh_sum;
        if (uh->uh_sum == 0) {
-               udpstat.udps_nosum++;
+               udpstat_inc(udps_nosum);
 #ifdef INET6
                /*
                 * In IPv6, the UDP checksum is ALWAYS used.
@@ -287,10 +289,10 @@ udp_input(struct mbuf *m, ...)
        } else {
                if ((m->m_pkthdr.csum_flags & M_UDP_CSUM_IN_OK) == 0) {
                        if (m->m_pkthdr.csum_flags & M_UDP_CSUM_IN_BAD) {
-                               udpstat.udps_badsum++;
+                               udpstat_inc(udps_badsum);
                                goto bad;
                        }
-                       udpstat.udps_inswcsum++;
+                       udpstat_inc(udps_inswcsum);
 
                        if (ip)
                                uh->uh_sum = in4_cksum(m, IPPROTO_UDP,
@@ -301,7 +303,7 @@ udp_input(struct mbuf *m, ...)
                                    iphlen, len);
 #endif /* INET6 */
                        if (uh->uh_sum != 0) {
-                               udpstat.udps_badsum++;
+                               udpstat_inc(udps_badsum);
                                goto bad;
                        }
                }
@@ -328,7 +330,7 @@ udp_input(struct mbuf *m, ...)
                 */
                if (spi != 0) {
                        if ((m = m_pullup(m, skip)) == NULL) {
-                               udpstat.udps_hdrops++;
+                               udpstat_inc(udps_hdrops);
                                return;
                        }
 
@@ -497,7 +499,7 @@ udp_input(struct mbuf *m, ...)
                                            &srcsa.sa, n, opts) == 0) {
                                                m_freem(n);
                                                m_freem(opts);
-                                               udpstat.udps_fullsock++;
+                                               udpstat_inc(udps_fullsock);
                                        } else
                                                sorwakeup(last->inp_socket);
                                        opts = NULL;
@@ -523,7 +525,7 @@ udp_input(struct mbuf *m, ...)
                         * (No need to send an ICMP Port Unreachable
                         * for a broadcast or multicast datgram.)
                         */
-                       udpstat.udps_noportbcast++;
+                       udpstat_inc(udps_noportbcast);
                        goto bad;
                }
 
@@ -539,7 +541,7 @@ udp_input(struct mbuf *m, ...)
                m_adj(m, iphlen);
                if (sbappendaddr(&last->inp_socket->so_rcv,
                    &srcsa.sa, m, opts) == 0) {
-                       udpstat.udps_fullsock++;
+                       udpstat_inc(udps_fullsock);
                        goto bad;
                }
                sorwakeup(last->inp_socket);
@@ -566,7 +568,7 @@ udp_input(struct mbuf *m, ...)
                int     inpl_reverse = 0;
                if (m->m_pkthdr.pf.flags & PF_TAG_TRANSLATE_LOCALHOST)
                        inpl_reverse = 1;
-               ++udpstat.udps_pcbhashmiss;
+               udpstat_inc(udps_pcbhashmiss);
 #ifdef INET6
                if (ip6) {
                        inp = in6_pcblookup_listen(&udbtable,
@@ -578,9 +580,9 @@ udp_input(struct mbuf *m, ...)
                    ip->ip_dst, uh->uh_dport, inpl_reverse, m,
                    m->m_pkthdr.ph_rtableid);
                if (inp == 0) {
-                       udpstat.udps_noport++;
+                       udpstat_inc(udps_noport);
                        if (m->m_flags & (M_BCAST | M_MCAST)) {
-                               udpstat.udps_noportbcast++;
+                               udpstat_inc(udps_noportbcast);
                                goto bad;
                        }
 #ifdef INET6
@@ -628,7 +630,7 @@ udp_input(struct mbuf *m, ...)
        ipsp_spd_lookup(m, srcsa.sa.sa_family, iphlen, &error,
            IPSP_DIRECTION_IN, tdb, inp, 0);
        if (error) {
-               udpstat.udps_nosec++;
+               udpstat_inc(udps_nosec);
                goto bad;
        }
        /* create ipsec options while we know that tdb cannot be modified */
@@ -690,7 +692,7 @@ udp_input(struct mbuf *m, ...)
        iphlen += sizeof(struct udphdr);
        m_adj(m, iphlen);
        if (sbappendaddr(&inp->inp_socket->so_rcv, &srcsa.sa, m, opts) == 0) {
-               udpstat.udps_fullsock++;
+               udpstat_inc(udps_fullsock);
                goto bad;
        }
        sorwakeup(inp->inp_socket);
@@ -1073,7 +1075,7 @@ udp_output(struct inpcb *inp, struct mbu
        if (udpcksum)
                m->m_pkthdr.csum_flags |= M_UDP_CSUM_OUT;
 
-       udpstat.udps_opackets++;
+       udpstat_inc(udps_opackets);
 
        /* force routing table */
        m->m_pkthdr.ph_rtableid = inp->inp_rtableid;
@@ -1341,8 +1343,8 @@ udp_sysctl(int *name, u_int namelen, voi
        case UDPCTL_STATS:
                if (newp != NULL)
                        return (EPERM);
-               return (sysctl_struct(oldp, oldlenp, newp, newlen,
-                   &udpstat, sizeof(udpstat)));
+
+               return (udp_sysctl_udpstat(oldp, oldlenp, newp));
 
        default:
                if (name[0] < UDPCTL_MAXID)
@@ -1351,4 +1353,23 @@ udp_sysctl(int *name, u_int namelen, voi
                return (ENOPROTOOPT);
        }
        /* NOTREACHED */
+}
+
+int
+udp_sysctl_udpstat(void *oldp, size_t *oldlenp, void *newp)
+{
+       uint64_t counters[udps_ncounters];
+       struct udpstat udpstat;
+       u_long *words = (u_long *)&udpstat;
+       int i;
+
+       KASSERT(sizeof(udpstat) == (nitems(counters) * sizeof(u_long)));
+
+       counters_read(udpcounters, counters, nitems(counters));
+
+       for (i = 0; i < nitems(counters); i++)
+               words[i] = (u_long)counters[i];
+
+       return (sysctl_rdstruct(oldp, oldlenp, newp,
+           &udpstat, sizeof(udpstat)));
 }
Index: netinet/udp_var.h
===================================================================
RCS file: /cvs/src/sys/netinet/udp_var.h,v
retrieving revision 1.27
diff -u -p -r1.27 udp_var.h
--- netinet/udp_var.h   18 Jun 2016 10:36:13 -0000      1.27
+++ netinet/udp_var.h   14 Nov 2016 04:27:42 -0000
@@ -102,6 +102,37 @@ struct     udpstat {
 }
 
 #ifdef _KERNEL
+
+#include <sys/percpu.h>
+
+enum udpstat_counters {
+                       /* input statistics: */
+       udps_ipackets,          /* total input packets */
+       udps_hdrops,            /* packet shorter than header */
+       udps_badsum,            /* checksum error */
+       udps_nosum,             /* no checksum */
+       udps_badlen,            /* data length larger than packet */
+       udps_noport,            /* no socket on port */
+       udps_noportbcast,       /* of above, arrived as broadcast */
+       udps_nosec,             /* dropped for lack of ipsec */
+       udps_fullsock,          /* not delivered, input socket full */
+       udps_pcbhashmiss,       /* input packets missing pcb hash */
+       udps_inswcsum,          /* input software-csummed packets */
+                       /* output statistics: */
+       udps_opackets,          /* total output packets */
+       udps_outswcsum,         /* output software-csummed packets */
+
+       udps_ncounters
+};
+
+extern struct cpumem *udpcounters;
+
+static inline void
+udpstat_inc(enum udpstat_counters c)
+{
+       counters_inc(udpcounters, c);
+}
+
 extern struct  inpcbtable udbtable;
 extern struct  udpstat udpstat;
 
Index: netinet6/ip6_output.c
===================================================================
RCS file: /cvs/src/sys/netinet6/ip6_output.c,v
retrieving revision 1.216
diff -u -p -r1.216 ip6_output.c
--- netinet6/ip6_output.c       19 Sep 2016 18:09:09 -0000      1.216
+++ netinet6/ip6_output.c       14 Nov 2016 04:27:43 -0000
@@ -2770,7 +2770,7 @@ in6_proto_cksum_out(struct mbuf *m, stru
                if (!ifp || !(ifp->if_capabilities & IFCAP_CSUM_UDPv6) ||
                    ip6->ip6_nxt != IPPROTO_UDP ||
                    ifp->if_bridgeport != NULL) {
-                       udpstat.udps_outswcsum++;
+                       udpstat_inc(udps_outswcsum);
                        in6_delayed_cksum(m, IPPROTO_UDP);
                        m->m_pkthdr.csum_flags &= ~M_UDP_CSUM_OUT; /* Clear */
                }
Index: netinet6/udp6_output.c
===================================================================
RCS file: /cvs/src/sys/netinet6/udp6_output.c,v
retrieving revision 1.51
diff -u -p -r1.51 udp6_output.c
--- netinet6/udp6_output.c      4 Aug 2016 20:46:24 -0000       1.51
+++ netinet6/udp6_output.c      14 Nov 2016 04:27:43 -0000
@@ -229,7 +229,7 @@ udp6_output(struct inpcb *in6p, struct m
        if (in6p->inp_flags & IN6P_MINMTU)
                flags |= IPV6_MINMTU;
 
-       udpstat.udps_opackets++;
+       udpstat_inc(udps_opackets);
 
        /* force routing table */
        m->m_pkthdr.ph_rtableid = in6p->inp_rtableid;

Reply via email to