summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/net/if_bridge.c20
-rw-r--r--sys/net/if_etherip.c4
-rw-r--r--sys/net/pf.c12
-rw-r--r--sys/netinet/ip_icmp.c4
-rw-r--r--sys/netinet/ip_input.c105
-rw-r--r--sys/netinet/ip_output.c26
-rw-r--r--sys/netinet/ip_var.h49
-rw-r--r--sys/netinet/raw_ip.c13
8 files changed, 153 insertions, 80 deletions
diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c
index 7b0c364cf60..e74be534663 100644
--- a/sys/net/if_bridge.c
+++ b/sys/net/if_bridge.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_bridge.c,v 1.287 2016/10/03 15:53:09 rzalamena Exp $ */
+/* $OpenBSD: if_bridge.c,v 1.288 2016/11/14 03:51:53 dlg Exp $ */
/*
* Copyright (c) 1999, 2000 Jason L. Wright (jason@thought.net)
@@ -1603,25 +1603,25 @@ bridge_ip(struct bridge_softc *sc, int dir, struct ifnet *ifp,
/* 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 dir, struct ifnet *ifp,
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 dir, struct ifnet *ifp,
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, struct ifnet *ifp,
}
if (error == 0)
- ipstat.ips_fragmented++;
+ ipstat_inc(ips_fragmented);
return;
dropit:
diff --git a/sys/net/if_etherip.c b/sys/net/if_etherip.c
index ad58c5208c5..d203fa2f8f5 100644
--- a/sys/net/if_etherip.c
+++ b/sys/net/if_etherip.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_etherip.c,v 1.7 2016/04/13 11:41:15 mpi Exp $ */
+/* $OpenBSD: if_etherip.c,v 1.8 2016/11/14 03:51:53 dlg Exp $ */
/*
* Copyright (c) 2015 Kazuya GODA <goda@openbsd.org>
*
@@ -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;
}
diff --git a/sys/net/pf.c b/sys/net/pf.c
index 1a9bd5ee2dd..903618151b5 100644
--- a/sys/net/pf.c
+++ b/sys/net/pf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf.c,v 1.996 2016/10/28 07:54:19 sashan Exp $ */
+/* $OpenBSD: pf.c,v 1.997 2016/11/14 03:51:53 dlg Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -5825,7 +5825,7 @@ pf_route(struct mbuf **m, struct pf_pdesc *pd, struct pf_rule *r,
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_pdesc *pd, struct pf_rule *r,
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_pdesc *pd, struct pf_rule *r,
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_pdesc *pd, struct pf_rule *r,
* 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_pdesc *pd, struct pf_rule *r,
}
if (error == 0)
- ipstat.ips_fragmented++;
+ ipstat_inc(ips_fragmented);
done:
if (r->rt != PF_DUPTO)
diff --git a/sys/netinet/ip_icmp.c b/sys/netinet/ip_icmp.c
index 959d32b200b..aaebccde226 100644
--- a/sys/netinet/ip_icmp.c
+++ b/sys/netinet/ip_icmp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_icmp.c,v 1.153 2016/11/09 09:04:48 mpi Exp $ */
+/* $OpenBSD: ip_icmp.c,v 1.154 2016/11/14 03:51:53 dlg Exp $ */
/* $NetBSD: ip_icmp.c,v 1.19 1996/02/13 23:42:22 christos Exp $ */
/*
@@ -751,7 +751,7 @@ icmp_reflect(struct mbuf *m, struct mbuf **op, struct in_ifaddr *ia)
/* 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);
}
diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c
index 447cc003b11..3b5ee43c05a 100644
--- a/sys/netinet/ip_input.c
+++ b/sys/netinet/ip_input.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_input.c,v 1.283 2016/11/08 10:45:08 mpi Exp $ */
+/* $OpenBSD: ip_input.c,v 1.284 2016/11/14 03:51:53 dlg Exp $ */
/* $NetBSD: ip_input.c,v 1.30 1996/03/16 23:53:58 christos Exp $ */
/*
@@ -120,7 +120,9 @@ struct niqueue ipintrq = NIQUEUE_INITIALIZER(IFQ_MAXLEN, NETISR_IP);
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 ifnet *, struct rtentry *, int);
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));
}
}
@@ -1246,7 +1250,7 @@ ip_dooptions(struct mbuf *m, struct ifnet *ifp)
bad:
KERNEL_UNLOCK();
icmp_error(m, type, code, 0, 0);
- ipstat.ips_badoptions++;
+ ipstat_inc(ips_badoptions);
return (1);
}
@@ -1396,7 +1400,7 @@ ip_forward(struct mbuf *m, struct ifnet *ifp, struct rtentry *rt, int srcrt)
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;
}
@@ -1477,11 +1481,11 @@ ip_forward(struct mbuf *m, struct ifnet *ifp, struct rtentry *rt, int srcrt)
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;
}
@@ -1521,7 +1525,7 @@ ip_forward(struct mbuf *m, struct ifnet *ifp, struct rtentry *rt, int srcrt)
}
}
#endif /*IPSEC*/
- ipstat.ips_cantfrag++;
+ ipstat_inc(ips_cantfrag);
break;
case EACCES:
@@ -1615,8 +1619,7 @@ ip_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
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,
@@ -1647,6 +1650,24 @@ ip_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
/* 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
ip_savecontrol(struct inpcb *inp, struct mbuf **mp, struct ip *ip,
struct mbuf *m)
diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c
index 2c0f416af9e..7ce0239c95f 100644
--- a/sys/netinet/ip_output.c
+++ b/sys/netinet/ip_output.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_output.c,v 1.327 2016/09/04 17:18:56 mpi Exp $ */
+/* $OpenBSD: ip_output.c,v 1.328 2016/11/14 03:51:53 dlg Exp $ */
/* $NetBSD: ip_output.c,v 1.28 1996/02/13 23:43:07 christos Exp $ */
/*
@@ -133,7 +133,7 @@ ip_output(struct mbuf *m0, struct mbuf *opt, struct route *ro, int flags,
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 *ifp, u_long mtu)
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 *ifp, u_long mtu)
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, u_long mtu)
(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, u_long mtu)
(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:
diff --git a/sys/netinet/ip_var.h b/sys/netinet/ip_var.h
index d86bec2257c..e4e364649c8 100644
--- a/sys/netinet/ip_var.h
+++ b/sys/netinet/ip_var.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_var.h,v 1.62 2016/04/15 11:18:40 mpi Exp $ */
+/* $OpenBSD: ip_var.h,v 1.63 2016/11/14 03:51:53 dlg Exp $ */
/* $NetBSD: ip_var.h,v 1.16 1996/02/13 23:43:20 christos Exp $ */
/*
@@ -96,6 +96,53 @@ struct ipoption {
#ifdef _KERNEL
+#include <sys/percpu.h>
+
+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.
diff --git a/sys/netinet/raw_ip.c b/sys/netinet/raw_ip.c
index 6c351200d80..147d6266e79 100644
--- a/sys/netinet/raw_ip.c
+++ b/sys/netinet/raw_ip.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: raw_ip.c,v 1.86 2016/03/07 18:44:00 naddy Exp $ */
+/* $OpenBSD: raw_ip.c,v 1.87 2016/11/14 03:51:53 dlg Exp $ */
/* $NetBSD: raw_ip.c,v 1.25 1996/02/18 18:58:33 christos Exp $ */
/*
@@ -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
/*