summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorvisa <visa@openbsd.org>2017-11-10 02:37:14 +0000
committervisa <visa@openbsd.org>2017-11-10 02:37:14 +0000
commitdd4faa4aa0268ad1b630c0ee8cdb1005151a235c (patch)
tree6a968c789e82df1a7067f45c1eb58e1125f03368
parentIf we successfully change the directory, set PWD too to give the shell a (diff)
downloadwireguard-openbsd-dd4faa4aa0268ad1b630c0ee8cdb1005151a235c.tar.xz
wireguard-openbsd-dd4faa4aa0268ad1b630c0ee8cdb1005151a235c.zip
Use percpu counters with etheripstat.
Input and OK jca@, OK florian@
-rw-r--r--sys/net/if_etherip.c52
-rw-r--r--sys/net/if_etherip.h1
-rw-r--r--sys/netinet/in_proto.c3
-rw-r--r--sys/netinet/ip_ether.c76
-rw-r--r--sys/netinet/ip_ether.h44
5 files changed, 109 insertions, 67 deletions
diff --git a/sys/net/if_etherip.c b/sys/net/if_etherip.c
index fecbd2f9d9c..b392bb69b92 100644
--- a/sys/net/if_etherip.c
+++ b/sys/net/if_etherip.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_etherip.c,v 1.21 2017/10/25 09:24:09 mpi Exp $ */
+/* $OpenBSD: if_etherip.c,v 1.22 2017/11/10 02:37:14 visa Exp $ */
/*
* Copyright (c) 2015 Kazuya GODA <goda@openbsd.org>
*
@@ -78,8 +78,6 @@ LIST_HEAD(, etherip_softc) etherip_softc_list;
* net.inet.etherip.allow value. Zero means drop them, all else is acceptance.
*/
int etherip_allow = 0;
-
-struct etheripstat etheripstat;
#endif
void etheripattach(int);
@@ -371,7 +369,7 @@ ip_etherip_output(struct ifnet *ifp, struct mbuf *m)
M_PREPEND(m, sizeof(struct etherip_header), M_DONTWAIT);
if (m == NULL) {
- etheripstat.etherips_adrops++;
+ etheripstat_inc(etherips_adrops);
return ENOBUFS;
}
eip = mtod(m, struct etherip_header *);
@@ -381,7 +379,7 @@ ip_etherip_output(struct ifnet *ifp, struct mbuf *m)
M_PREPEND(m, sizeof(struct ip), M_DONTWAIT);
if (m == NULL) {
- etheripstat.etherips_adrops++;
+ etheripstat_inc(etherips_adrops);
return ENOBUFS;
}
ip = mtod(m, struct ip *);
@@ -402,8 +400,7 @@ ip_etherip_output(struct ifnet *ifp, struct mbuf *m)
#if NPF > 0
pf_pkt_addr_changed(m);
#endif
- etheripstat.etherips_opackets++;
- etheripstat.etherips_obytes += (m->m_pkthdr.len -
+ etheripstat_pkt(etherips_opackets, etherips_obytes, m->m_pkthdr.len -
(sizeof(struct ip) + sizeof(struct etherip_header)));
return ip_output(m, NULL, NULL, IP_RAWOUTPUT, NULL, NULL, 0);
@@ -430,7 +427,7 @@ ip_etherip_input(struct mbuf **mp, int *offp, int proto, int af)
if (!etherip_allow && (m->m_flags & (M_AUTH|M_CONF)) == 0) {
m_freem(m);
- etheripstat.etherips_pdrops++;
+ etheripstat_inc(etherips_pdrops);
return IPPROTO_DONE;
}
@@ -460,7 +457,7 @@ ip_etherip_input(struct mbuf **mp, int *offp, int proto, int af)
*/
return etherip_input(mp, offp, proto, af);
#else
- etheripstat.etherips_noifdrops++;
+ etheripstat_inc(etherips_noifdrops);
m_freem(m);
return IPPROTO_DONE;
#endif /* NGIF */
@@ -469,25 +466,24 @@ ip_etherip_input(struct mbuf **mp, int *offp, int proto, int af)
m_adj(m, *offp);
m = *mp = m_pullup(m, sizeof(struct etherip_header));
if (m == NULL) {
- etheripstat.etherips_adrops++;
+ etheripstat_inc(etherips_adrops);
return IPPROTO_DONE;
}
eip = mtod(m, struct etherip_header *);
if (eip->eip_ver != ETHERIP_VERSION || eip->eip_pad) {
- etheripstat.etherips_adrops++;
+ etheripstat_inc(etherips_adrops);
m_freem(m);
return IPPROTO_DONE;
}
- etheripstat.etherips_ipackets++;
- etheripstat.etherips_ibytes += (m->m_pkthdr.len -
+ etheripstat_pkt(etherips_ipackets, etherips_ibytes, m->m_pkthdr.len -
sizeof(struct etherip_header));
m_adj(m, sizeof(struct etherip_header));
m = *mp = m_pullup(m, sizeof(struct ether_header));
if (m == NULL) {
- etheripstat.etherips_adrops++;
+ etheripstat_inc(etherips_adrops);
return IPPROTO_DONE;
}
m->m_flags &= ~(M_BCAST|M_MCAST);
@@ -532,7 +528,7 @@ ip6_etherip_output(struct ifnet *ifp, struct mbuf *m)
M_PREPEND(m, sizeof(struct etherip_header), M_DONTWAIT);
if (m == NULL) {
- etheripstat.etherips_adrops++;
+ etheripstat_inc(etherips_adrops);
return ENOBUFS;
}
eip = mtod(m, struct etherip_header *);
@@ -542,7 +538,7 @@ ip6_etherip_output(struct ifnet *ifp, struct mbuf *m)
M_PREPEND(m, sizeof(struct ip6_hdr), M_DONTWAIT);
if (m == NULL) {
- etheripstat.etherips_adrops++;
+ etheripstat_inc(etherips_adrops);
return ENOBUFS;
}
ip6 = mtod(m, struct ip6_hdr *);
@@ -564,8 +560,7 @@ ip6_etherip_output(struct ifnet *ifp, struct mbuf *m)
#if NPF > 0
pf_pkt_addr_changed(m);
#endif
- etheripstat.etherips_opackets++;
- etheripstat.etherips_obytes += (m->m_pkthdr.len -
+ etheripstat_pkt(etherips_opackets, etherips_obytes, m->m_pkthdr.len -
(sizeof(struct ip6_hdr) + sizeof(struct etherip_header)));
return ip6_output(m, 0, NULL, IPV6_MINMTU, 0, NULL);
@@ -590,7 +585,7 @@ ip6_etherip_input(struct mbuf **mp, int *offp, int proto, int af)
if (!etherip_allow && (m->m_flags & (M_AUTH|M_CONF)) == 0) {
m_freem(m);
- etheripstat.etherips_pdrops++;
+ etheripstat_inc(etherips_pdrops);
return IPPROTO_NONE;
}
@@ -624,7 +619,7 @@ ip6_etherip_input(struct mbuf **mp, int *offp, int proto, int af)
*/
return etherip_input(mp, offp, proto, af);
#else
- etheripstat.etherips_noifdrops++;
+ etheripstat_inc(etherips_noifdrops);
m_freem(m);
return IPPROTO_DONE;
#endif /* NGIF */
@@ -633,24 +628,23 @@ ip6_etherip_input(struct mbuf **mp, int *offp, int proto, int af)
m_adj(m, *offp);
m = *mp = m_pullup(m, sizeof(struct etherip_header));
if (m == NULL) {
- etheripstat.etherips_adrops++;
+ etheripstat_inc(etherips_adrops);
return IPPROTO_DONE;
}
eip = mtod(m, struct etherip_header *);
if ((eip->eip_ver != ETHERIP_VERSION) || eip->eip_pad) {
- etheripstat.etherips_adrops++;
+ etheripstat_inc(etherips_adrops);
m_freem(m);
return IPPROTO_DONE;
}
- etheripstat.etherips_ipackets++;
- etheripstat.etherips_ibytes += (m->m_pkthdr.len -
+ etheripstat_pkt(etherips_ipackets, etherips_ibytes, m->m_pkthdr.len -
sizeof(struct etherip_header));
m_adj(m, sizeof(struct etherip_header));
m = *mp = m_pullup(m, sizeof(struct ether_header));
if (m == NULL) {
- etheripstat.etherips_adrops++;
+ etheripstat_inc(etherips_adrops);
return IPPROTO_DONE;
}
@@ -683,13 +677,7 @@ ip_etherip_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp,
NET_UNLOCK();
return (error);
case ETHERIPCTL_STATS:
- if (newp != NULL)
- return EPERM;
- NET_LOCK();
- error = sysctl_struct(oldp, oldlenp, newp, newlen,
- &etheripstat, sizeof(etheripstat));
- NET_UNLOCK();
- return (error);
+ return (etherip_sysctl_etheripstat(oldp, oldlenp, newp));
default:
break;
}
diff --git a/sys/net/if_etherip.h b/sys/net/if_etherip.h
index f4c205632ed..6349e671850 100644
--- a/sys/net/if_etherip.h
+++ b/sys/net/if_etherip.h
@@ -27,7 +27,6 @@
*/
extern int etherip_allow;
-extern struct etheripstat etheripstat;
struct etheripstat {
u_int64_t etherips_hdrops; /* packet shorter than header shows */
diff --git a/sys/netinet/in_proto.c b/sys/netinet/in_proto.c
index 3104a8ff6f3..56a81dee3d8 100644
--- a/sys/netinet/in_proto.c
+++ b/sys/netinet/in_proto.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: in_proto.c,v 1.81 2017/11/05 13:19:59 florian Exp $ */
+/* $OpenBSD: in_proto.c,v 1.82 2017/11/10 02:37:14 visa Exp $ */
/* $NetBSD: in_proto.c,v 1.14 1996/02/18 18:58:32 christos Exp $ */
/*
@@ -279,6 +279,7 @@ struct protosw inetsw[] = {
.pr_usrreq = rip_usrreq,
.pr_attach = rip_attach,
.pr_detach = rip_detach,
+ .pr_init = etherip_init,
.pr_sysctl = etherip_sysctl
},
#endif /* NGIF */
diff --git a/sys/netinet/ip_ether.c b/sys/netinet/ip_ether.c
index 1ff526cb0dd..7bc9267949f 100644
--- a/sys/netinet/ip_ether.c
+++ b/sys/netinet/ip_ether.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_ether.c,v 1.88 2017/11/06 15:12:43 mpi Exp $ */
+/* $OpenBSD: ip_ether.c,v 1.89 2017/11/10 02:37:14 visa Exp $ */
/*
* The author of this code is Angelos D. Keromytis (kermit@adk.gr)
*
@@ -82,7 +82,13 @@ struct gif_softc *etherip_getgif(struct mbuf *);
*/
int etherip_allow = 0;
-struct etheripstat etheripstat;
+struct cpumem *etheripcounters;
+
+void
+etherip_init(void)
+{
+ etheripcounters = counters_alloc(etherips_ncounters);
+}
/*
* etherip_input gets called when we receive an encapsulated packet.
@@ -96,7 +102,7 @@ etherip_input(struct mbuf **mp, int *offp, int proto, int af)
/* If we do not accept EtherIP explicitly, drop. */
if (!etherip_allow && ((*mp)->m_flags & (M_AUTH|M_CONF)) == 0) {
DPRINTF(("%s: dropped due to policy\n", __func__));
- etheripstat.etherips_pdrops++;
+ etheripstat_inc(etherips_pdrops);
m_freemp(mp);
return IPPROTO_DONE;
}
@@ -110,7 +116,7 @@ etherip_input(struct mbuf **mp, int *offp, int proto, int af)
#endif
default:
DPRINTF(("%s: dropped, unhandled protocol\n", __func__));
- etheripstat.etherips_pdrops++;
+ etheripstat_inc(etherips_pdrops);
m_freemp(mp);
return IPPROTO_DONE;
}
@@ -124,7 +130,7 @@ etherip_decap(struct mbuf *m, int iphlen)
struct gif_softc *sc;
struct mbuf_list ml = MBUF_LIST_INITIALIZER();
- etheripstat.etherips_ipackets++;
+ etheripstat_inc(etherips_ipackets);
/*
* Make sure there's at least an ethernet header's and an EtherIP
@@ -133,7 +139,7 @@ etherip_decap(struct mbuf *m, int iphlen)
if (m->m_pkthdr.len < iphlen + sizeof(struct ether_header) +
sizeof(struct etherip_header)) {
DPRINTF(("%s: encapsulated packet too short\n", __func__));
- etheripstat.etherips_hdrops++;
+ etheripstat_inc(etherips_hdrops);
m_freem(m);
return;
}
@@ -145,7 +151,7 @@ etherip_decap(struct mbuf *m, int iphlen)
} else {
DPRINTF(("%s: received EtherIP version number %d not "
"supported\n", __func__, eip.eip_ver));
- etheripstat.etherips_adrops++;
+ etheripstat_inc(etherips_adrops);
m_freem(m);
return;
}
@@ -153,7 +159,7 @@ etherip_decap(struct mbuf *m, int iphlen)
/* Finally, the pad value must be zero. */
if (eip.eip_pad) {
DPRINTF(("%s: received EtherIP invalid pad value\n", __func__));
- etheripstat.etherips_adrops++;
+ etheripstat_inc(etherips_adrops);
m_freem(m);
return;
}
@@ -164,7 +170,7 @@ etherip_decap(struct mbuf *m, int iphlen)
if ((m = m_pullup(m, iphlen + sizeof(struct ether_header) +
sizeof(struct etherip_header))) == NULL) {
DPRINTF(("%s: m_pullup() failed\n", __func__));
- etheripstat.etherips_adrops++;
+ etheripstat_inc(etherips_adrops);
return;
}
}
@@ -174,7 +180,7 @@ etherip_decap(struct mbuf *m, int iphlen)
return;
if (sc->gif_if.if_bridgeport == NULL) {
DPRINTF(("%s: interface not part of bridge\n", __func__));
- etheripstat.etherips_noifdrops++;
+ etheripstat_inc(etherips_noifdrops);
m_freem(m);
return;
}
@@ -183,7 +189,7 @@ etherip_decap(struct mbuf *m, int iphlen)
m_adj(m, iphlen + sizeof(struct etherip_header));
/* Statistics */
- etheripstat.etherips_ibytes += m->m_pkthdr.len;
+ etheripstat_add(etherips_ibytes, m->m_pkthdr.len);
/* Reset the flags based on the inner packet */
m->m_flags &= ~(M_BCAST|M_MCAST|M_AUTH|M_CONF|M_PROTO1);
@@ -203,7 +209,7 @@ mplsip_decap(struct mbuf *m, int iphlen)
{
struct gif_softc *sc;
- etheripstat.etherips_ipackets++;
+ etheripstat_inc(etherips_ipackets);
/*
* Make sure there's at least one MPLS label worth of data after
@@ -211,7 +217,7 @@ mplsip_decap(struct mbuf *m, int iphlen)
*/
if (m->m_pkthdr.len < iphlen + sizeof(struct shim_hdr)) {
DPRINTF(("%s: encapsulated packet too short\n", __func__));
- etheripstat.etherips_hdrops++;
+ etheripstat_inc(etherips_hdrops);
m_freem(m);
return;
}
@@ -221,7 +227,7 @@ mplsip_decap(struct mbuf *m, int iphlen)
if ((m = m_pullup(m, iphlen + sizeof(struct shim_hdr))) ==
NULL) {
DPRINTF(("%s: m_pullup() failed\n", __func__));
- etheripstat.etherips_adrops++;
+ etheripstat_inc(etherips_adrops);
return;
}
}
@@ -234,7 +240,7 @@ mplsip_decap(struct mbuf *m, int iphlen)
m_adj(m, iphlen);
/* Statistics */
- etheripstat.etherips_ibytes += m->m_pkthdr.len;
+ etheripstat_add(etherips_ibytes, m->m_pkthdr.len);
/* Reset the flags based */
m->m_flags &= ~(M_BCAST|M_MCAST);
@@ -292,7 +298,7 @@ etherip_getgif(struct mbuf *m)
default:
DPRINTF(("%s: invalid protocol %d\n", __func__, v));
m_freem(m);
- etheripstat.etherips_hdrops++;
+ etheripstat_inc(etherips_hdrops);
return NULL;
}
@@ -311,7 +317,7 @@ etherip_getgif(struct mbuf *m)
/* None found. */
if (sc == NULL) {
DPRINTF(("%s: no interface found\n", __func__));
- etheripstat.etherips_noifdrops++;
+ etheripstat_inc(etherips_noifdrops);
m_freem(m);
return NULL;
}
@@ -335,7 +341,7 @@ etherip_output(struct mbuf *m, struct tdb *tdb, struct mbuf **mp, int proto)
(tdb->tdb_src.sa.sa_family != AF_INET6)) {
DPRINTF(("%s: IP in protocol-family <%d> attempted, aborting",
__func__, tdb->tdb_src.sa.sa_family));
- etheripstat.etherips_adrops++;
+ etheripstat_inc(etherips_adrops);
m_freem(m);
return EINVAL;
}
@@ -344,7 +350,7 @@ etherip_output(struct mbuf *m, struct tdb *tdb, struct mbuf **mp, int proto)
(tdb->tdb_dst.sa.sa_family != AF_INET6)) {
DPRINTF(("%s: IP in protocol-family <%d> attempted, aborting",
__func__, tdb->tdb_dst.sa.sa_family));
- etheripstat.etherips_adrops++;
+ etheripstat_inc(etherips_adrops);
m_freem(m);
return EINVAL;
}
@@ -353,7 +359,7 @@ etherip_output(struct mbuf *m, struct tdb *tdb, struct mbuf **mp, int proto)
DPRINTF(("%s: mismatch in tunnel source and destination address"
" protocol families (%d/%d), aborting", __func__,
tdb->tdb_src.sa.sa_family, tdb->tdb_dst.sa.sa_family));
- etheripstat.etherips_adrops++;
+ etheripstat_inc(etherips_adrops);
m_freem(m);
return EINVAL;
}
@@ -370,7 +376,7 @@ etherip_output(struct mbuf *m, struct tdb *tdb, struct mbuf **mp, int proto)
default:
DPRINTF(("%s: unsupported tunnel protocol family <%d>, "
"aborting", __func__, tdb->tdb_dst.sa.sa_family));
- etheripstat.etherips_adrops++;
+ etheripstat_inc(etherips_adrops);
m_freem(m);
return EINVAL;
}
@@ -382,7 +388,7 @@ etherip_output(struct mbuf *m, struct tdb *tdb, struct mbuf **mp, int proto)
M_PREPEND(m, hlen, M_DONTWAIT);
if (m == NULL) {
DPRINTF(("%s: M_PREPEND failed\n", __func__));
- etheripstat.etherips_adrops++;
+ etheripstat_inc(etherips_adrops);
return ENOBUFS;
}
@@ -399,8 +405,8 @@ etherip_output(struct mbuf *m, struct tdb *tdb, struct mbuf **mp, int proto)
}
/* Statistics */
- etheripstat.etherips_opackets++;
- etheripstat.etherips_obytes += m->m_pkthdr.len - hlen;
+ etheripstat_pkt(etherips_opackets, etherips_obytes,
+ m->m_pkthdr.len - hlen);
switch (tdb->tdb_dst.sa.sa_family) {
case AF_INET:
@@ -481,15 +487,23 @@ etherip_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp,
NET_UNLOCK();
return (error);
case ETHERIPCTL_STATS:
- if (newp != NULL)
- return (EPERM);
- NET_LOCK();
- error = sysctl_struct(oldp, oldlenp, newp, newlen,
- &etheripstat, sizeof(etheripstat));
- NET_UNLOCK();
- return (error);
+ return (etherip_sysctl_etheripstat(oldp, oldlenp, newp));
default:
return (ENOPROTOOPT);
}
/* NOTREACHED */
}
+
+int
+etherip_sysctl_etheripstat(void *oldp, size_t *oldlenp, void *newp)
+{
+ struct etheripstat etheripstat;
+
+ CTASSERT(sizeof(etheripstat) == (etherips_ncounters *
+ sizeof(uint64_t)));
+ memset(&etheripstat, 0, sizeof etheripstat);
+ counters_read(etheripcounters, (uint64_t *)&etheripstat,
+ etherips_ncounters);
+ return (sysctl_rdstruct(oldp, oldlenp, newp, &etheripstat,
+ sizeof(etheripstat)));
+}
diff --git a/sys/netinet/ip_ether.h b/sys/netinet/ip_ether.h
index 88f6875eaa1..d48ca952a46 100644
--- a/sys/netinet/ip_ether.h
+++ b/sys/netinet/ip_ether.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_ether.h,v 1.22 2017/04/14 20:46:31 bluhm Exp $ */
+/* $OpenBSD: ip_ether.h,v 1.23 2017/11/10 02:37:14 visa Exp $ */
/*
* The author of this code is Angelos D. Keromytis (angelos@adk.gr)
*
@@ -69,13 +69,53 @@ struct etherip_header {
}
#ifdef _KERNEL
+
+#include <sys/percpu.h>
+
+enum etheripstat_counters {
+ etherips_hdrops, /* packet shorter than header shows */
+ etherips_qfull, /* bridge queue full, packet dropped */
+ etherips_noifdrops, /* no interface/bridge information */
+ etherips_pdrops, /* packet dropped due to policy */
+ etherips_adrops, /* all other drops */
+ etherips_ipackets, /* total input packets */
+ etherips_opackets, /* total output packets */
+ etherips_ibytes, /* input bytes */
+ etherips_obytes, /* output bytes */
+
+ etherips_ncounters
+};
+
+extern struct cpumem *etheripcounters;
+
+static inline void
+etheripstat_inc(enum etheripstat_counters c)
+{
+ counters_inc(etheripcounters, c);
+}
+
+static inline void
+etheripstat_add(enum etheripstat_counters c, uint64_t v)
+{
+ counters_add(etheripcounters, c, v);
+}
+
+static inline void
+etheripstat_pkt(enum etheripstat_counters pcounter,
+ enum etheripstat_counters bcounter, uint64_t v)
+{
+ counters_pkt(etheripcounters, pcounter, bcounter, v);
+}
+
struct tdb;
+void etherip_init(void);
int etherip_output(struct mbuf *, struct tdb *, struct mbuf **, int);
int etherip_input(struct mbuf **, int *, int, int);
int etherip_sysctl(int *, u_int, void *, size_t *, void *, size_t);
+int etherip_sysctl_etheripstat(void *, size_t *, void *);
extern int etherip_allow;
-extern struct etheripstat etheripstat;
+
#endif /* _KERNEL */
#endif /* _NETINET_IP_ETHER_H_ */