Alexander Bluhm <alexander.bl...@gmx.net> writes:

> On Tue, Mar 07, 2017 at 06:16:30PM +0100, Jeremie Courreges-Anglas wrote:
>> 
>> I failed to find a nice place where to initialize the counters.  The
>> code that uses counters is reachable even if gif(4) isn't compiled in.
>> 
>> I can think of 3 obvious ways to call the init function.
>> 
>> 1. call ipip_init() through .pr_init.  The idea would be to call
>>    ipip_init() once per protosw entry that needs it, so the function
>>    should return early if it was already run.
>> 
>> 2. call ipip_init() from ip_init(), after all ip_init() is always
>>    compiled in.
>> 
>> 3. call ipip_init() from init_main.c.
>> 
>> The diff implements option 3, but what do you folks prefer?
>> Thoughts / ok?
>
> I would use option 2 as ip_ipip.c is always comiled in.  Then you
> don't need the "if (ipipcounters == NULL)" check.
>
> OK bluhm@

So here's a refreshed diff that initializes the counters directly from
ip_init().  I remove the ipip_init() wrapper to make it clear that
ip_init() is responsible for the job.

(Still) ok?


Index: netinet/ip_input.c
===================================================================
RCS file: /d/cvs/src/sys/netinet/ip_input.c,v
retrieving revision 1.295
diff -u -p -r1.295 ip_input.c
--- netinet/ip_input.c  5 Feb 2017 16:23:38 -0000       1.295
+++ netinet/ip_input.c  8 Mar 2017 10:19:34 -0000
@@ -34,6 +34,7 @@
 
 #include "pf.h"
 #include "carp.h"
+#include "gif.h"
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -78,6 +79,10 @@
 #include <netinet/ip_carp.h>
 #endif
 
+#if NGIF > 0
+#include <netinet/ip_ipip.h>
+#endif
+
 struct ipqhead ipq;
 
 int encdebug = 0;
@@ -168,6 +173,9 @@ ip_init(void)
        const u_int16_t defrootonlyports_udp[] = DEFROOTONLYPORTS_UDP;
 
        ipcounters = counters_alloc(ips_ncounters);
+#if NGIF > 0
+       ipipcounters = counters_alloc(ipips_ncounters);
+#endif
 
        pool_init(&ipqent_pool, sizeof(struct ipqent), 0,
            IPL_SOFTNET, 0, "ipqe",  NULL);
Index: netinet/ip_ipip.c
===================================================================
RCS file: /d/cvs/src/sys/netinet/ip_ipip.c,v
retrieving revision 1.71
diff -u -p -r1.71 ip_ipip.c
--- netinet/ip_ipip.c   29 Jan 2017 19:58:47 -0000      1.71
+++ netinet/ip_ipip.c   8 Mar 2017 10:20:44 -0000
@@ -84,7 +84,7 @@
  */
 int ipip_allow = 0;
 
-struct ipipstat ipipstat;
+struct cpumem *ipipcounters;
 
 /*
  * Really only a wrapper for ipip_input(), for use with pr_input.
@@ -95,7 +95,7 @@ ip4_input(struct mbuf **mp, int *offp, i
        /* If we do not accept IP-in-IP explicitly, drop.  */
        if (!ipip_allow && ((*mp)->m_flags & (M_AUTH|M_CONF)) == 0) {
                DPRINTF(("ip4_input(): dropped due to policy\n"));
-               ipipstat.ipips_pdrops++;
+               ipipstat_inc(ipips_pdrops);
                m_freem(*mp);
                return IPPROTO_DONE;
        }
@@ -129,7 +129,7 @@ ipip_input(struct mbuf **mp, int *offp, 
        u_int8_t v;
        sa_family_t af;
 
-       ipipstat.ipips_ipackets++;
+       ipipstat_inc(ipips_ipackets);
 
        m_copydata(m, 0, 1, &v);
 
@@ -143,7 +143,7 @@ ipip_input(struct mbuf **mp, int *offp, 
                break;
 #endif
        default:
-               ipipstat.ipips_family++;
+               ipipstat_inc(ipips_family);
                m_freem(m);
                return IPPROTO_DONE;
        }
@@ -152,7 +152,7 @@ ipip_input(struct mbuf **mp, int *offp, 
        if (m->m_len < hlen) {
                if ((m = m_pullup(m, hlen)) == NULL) {
                        DPRINTF(("ipip_input(): m_pullup() failed\n"));
-                       ipipstat.ipips_hdrops++;
+                       ipipstat_inc(ipips_hdrops);
                        return IPPROTO_DONE;
                }
        }
@@ -179,7 +179,7 @@ ipip_input(struct mbuf **mp, int *offp, 
 
        /* Sanity check */
        if (m->m_pkthdr.len < sizeof(struct ip)) {
-               ipipstat.ipips_hdrops++;
+               ipipstat_inc(ipips_hdrops);
                m_freem(m);
                return IPPROTO_DONE;
        }
@@ -195,7 +195,7 @@ ipip_input(struct mbuf **mp, int *offp, 
                break;
 #endif
        default:
-               ipipstat.ipips_family++;
+               ipipstat_inc(ipips_family);
                m_freem(m);
                return IPPROTO_DONE;
        }
@@ -206,7 +206,7 @@ ipip_input(struct mbuf **mp, int *offp, 
        if (m->m_len < hlen) {
                if ((m = m_pullup(m, hlen)) == NULL) {
                        DPRINTF(("ipip_input(): m_pullup() failed\n"));
-                       ipipstat.ipips_hdrops++;
+                       ipipstat_inc(ipips_hdrops);
                        return IPPROTO_DONE;
                }
        }
@@ -229,7 +229,7 @@ ipip_input(struct mbuf **mp, int *offp, 
                    ECN_ALLOWED_IPSEC : ECN_ALLOWED;
                if (!ip_ecn_egress(mode, &otos, &ipo->ip_tos)) {
                        DPRINTF(("ipip_input(): ip_ecn_egress() failed"));
-                       ipipstat.ipips_pdrops++;
+                       ipipstat_inc(ipips_pdrops);
                        m_freem(m);
                        return IPPROTO_DONE;
                }
@@ -249,7 +249,7 @@ ipip_input(struct mbuf **mp, int *offp, 
                itos = (ntohl(ip6->ip6_flow) >> 20) & 0xff;
                if (!ip_ecn_egress(ECN_ALLOWED, &otos, &itos)) {
                        DPRINTF(("ipip_input(): ip_ecn_egress() failed"));
-                       ipipstat.ipips_pdrops++;
+                       ipipstat_inc(ipips_pdrops);
                        m_freem(m);
                        return IPPROTO_DONE;
                }
@@ -291,7 +291,7 @@ ipip_input(struct mbuf **mp, int *offp, 
                rt = rtalloc((struct sockaddr *)&ss, 0,
                    m->m_pkthdr.ph_rtableid);
                if ((rt != NULL) && (rt->rt_flags & RTF_LOCAL)) {
-                       ipipstat.ipips_spoof++;
+                       ipipstat_inc(ipips_spoof);
                        m_freem(m);
                        rtfree(rt);
                        return IPPROTO_DONE;
@@ -302,7 +302,7 @@ ipip_input(struct mbuf **mp, int *offp, 
        }
 
        /* Statistics */
-       ipipstat.ipips_ibytes += m->m_pkthdr.len - iphlen;
+       ipipstat_add(ipips_ibytes, m->m_pkthdr.len - iphlen);
 
        /*
         * Interface pointer stays the same; if no IPsec processing has
@@ -336,7 +336,7 @@ ipip_input(struct mbuf **mp, int *offp, 
 #endif
 
        if (niq_enqueue(ifq, m) != 0) {
-               ipipstat.ipips_qfull++;
+               ipipstat_inc(ipips_qfull);
                DPRINTF(("ipip_input(): packet dropped because of full "
                    "queue\n"));
        }
@@ -375,7 +375,7 @@ ipip_output(struct mbuf *m, struct tdb *
                            ipsp_address(&tdb->tdb_dst, buf, sizeof(buf)),
                            ntohl(tdb->tdb_spi)));
 
-                       ipipstat.ipips_unspec++;
+                       ipipstat_inc(ipips_unspec);
                        m_freem(m);
                        *mp = NULL;
                        return EINVAL;
@@ -384,7 +384,7 @@ ipip_output(struct mbuf *m, struct tdb *
                M_PREPEND(m, sizeof(struct ip), M_DONTWAIT);
                if (m == NULL) {
                        DPRINTF(("ipip_output(): M_PREPEND failed\n"));
-                       ipipstat.ipips_hdrops++;
+                       ipipstat_inc(ipips_hdrops);
                        *mp = NULL;
                        return ENOBUFS;
                }
@@ -441,7 +441,7 @@ ipip_output(struct mbuf *m, struct tdb *
                else {
                        m_freem(m);
                        *mp = NULL;
-                       ipipstat.ipips_family++;
+                       ipipstat_inc(ipips_family);
                        return EAFNOSUPPORT;
                }
 
@@ -461,7 +461,7 @@ ipip_output(struct mbuf *m, struct tdb *
                            ipsp_address(&tdb->tdb_dst, buf, sizeof(buf)),
                            ntohl(tdb->tdb_spi)));
 
-                       ipipstat.ipips_unspec++;
+                       ipipstat_inc(ipips_unspec);
                        m_freem(m);
                        *mp = NULL;
                        return ENOBUFS;
@@ -480,7 +480,7 @@ ipip_output(struct mbuf *m, struct tdb *
                M_PREPEND(m, sizeof(struct ip6_hdr), M_DONTWAIT);
                if (m == NULL) {
                        DPRINTF(("ipip_output(): M_PREPEND failed\n"));
-                       ipipstat.ipips_hdrops++;
+                       ipipstat_inc(ipips_hdrops);
                        *mp = NULL;
                        return ENOBUFS;
                }
@@ -518,7 +518,7 @@ ipip_output(struct mbuf *m, struct tdb *
                        } else {
                                m_freem(m);
                                *mp = NULL;
-                               ipipstat.ipips_family++;
+                               ipipstat_inc(ipips_family);
                                return EAFNOSUPPORT;
                        }
 
@@ -533,11 +533,11 @@ ipip_output(struct mbuf *m, struct tdb *
                    tdb->tdb_dst.sa.sa_family));
                m_freem(m);
                *mp = NULL;
-               ipipstat.ipips_family++;
+               ipipstat_inc(ipips_family);
                return EAFNOSUPPORT;
        }
 
-       ipipstat.ipips_opackets++;
+       ipipstat_inc(ipips_opackets);
        *mp = m;
 
        if (tdb->tdb_dst.sa.sa_family == AF_INET) {
@@ -545,7 +545,7 @@ ipip_output(struct mbuf *m, struct tdb *
                        tdb->tdb_cur_bytes +=
                            m->m_pkthdr.len - sizeof(struct ip);
 
-               ipipstat.ipips_obytes += m->m_pkthdr.len - sizeof(struct ip);
+               ipipstat_add(ipips_obytes, m->m_pkthdr.len - sizeof(struct ip));
        }
 
 #ifdef INET6
@@ -554,8 +554,8 @@ ipip_output(struct mbuf *m, struct tdb *
                        tdb->tdb_cur_bytes +=
                            m->m_pkthdr.len - sizeof(struct ip6_hdr);
 
-               ipipstat.ipips_obytes +=
-                   m->m_pkthdr.len - sizeof(struct ip6_hdr);
+               ipipstat_add(ipips_obytes,
+                   m->m_pkthdr.len - sizeof(struct ip6_hdr));
        }
 #endif /* INET6 */
 
@@ -592,6 +592,17 @@ ipe4_input(struct mbuf *m, int hlen, int
 #endif /* IPSEC */
 
 int
+ipip_sysctl_ipipstat(void *oldp, size_t *oldlenp, void *newp)
+{
+       struct ipipstat ipipstat;
+
+       CTASSERT(sizeof(ipipstat) == (ipips_ncounters * sizeof(uint64_t)));
+       counters_read(ipipcounters, (uint64_t *)&ipipstat, ipips_ncounters);
+       return (sysctl_rdstruct(oldp, oldlenp, newp,
+           &ipipstat, sizeof(ipipstat)));
+}
+
+int
 ipip_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
     size_t newlen)
 {
@@ -603,10 +614,7 @@ ipip_sysctl(int *name, u_int namelen, vo
        case IPIPCTL_ALLOW:
                return (sysctl_int(oldp, oldlenp, newp, newlen, &ipip_allow));
        case IPIPCTL_STATS:
-               if (newp != NULL)
-                       return (EPERM);
-               return (sysctl_struct(oldp, oldlenp, newp, newlen,
-                   &ipipstat, sizeof(ipipstat)));
+               return (ipip_sysctl_ipipstat(oldp, oldlenp, newp));
        default:
                return (ENOPROTOOPT);
        }
Index: netinet/ip_ipip.h
===================================================================
RCS file: /d/cvs/src/sys/netinet/ip_ipip.h,v
retrieving revision 1.7
diff -u -p -r1.7 ip_ipip.h
--- netinet/ip_ipip.h   20 Feb 2017 17:04:25 -0000      1.7
+++ netinet/ip_ipip.h   7 Mar 2017 14:20:17 -0000
@@ -73,9 +73,39 @@ struct ipipstat {
 }
 
 #ifdef _KERNEL
+
+#include <sys/percpu.h>
+
+enum ipipstat_counters {
+       ipips_ipackets,
+       ipips_opackets,
+       ipips_hdrops,
+       ipips_qfull,
+       ipips_ibytes,
+       ipips_obytes,
+       ipips_pdrops,
+       ipips_spoof,
+       ipips_family,
+       ipips_unspec,
+       ipips_ncounters
+};
+
+extern struct cpumem *ipipcounters;
+
+static inline void
+ipipstat_inc(enum ipipstat_counters c)
+{
+       counters_inc(ipipcounters, c);
+}
+
+static inline void
+ipipstat_add(enum ipipstat_counters c, uint64_t v)
+{
+       counters_add(ipipcounters, c, v);
+}
+
 int    ipip_sysctl(int *, u_int, void *, size_t *, void *, size_t);
 
 extern int ipip_allow;
-extern struct ipipstat ipipstat;
 #endif /* _KERNEL */
 #endif /* _NETINET_IPIP_H_ */


-- 
jca | PGP : 0x1524E7EE / 5135 92C1 AD36 5293 2BDF  DDCC 0DFA 74AE 1524 E7EE

Reply via email to