diff options
author | 2017-11-10 02:37:14 +0000 | |
---|---|---|
committer | 2017-11-10 02:37:14 +0000 | |
commit | dd4faa4aa0268ad1b630c0ee8cdb1005151a235c (patch) | |
tree | 6a968c789e82df1a7067f45c1eb58e1125f03368 | |
parent | If we successfully change the directory, set PWD too to give the shell a (diff) | |
download | wireguard-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.c | 52 | ||||
-rw-r--r-- | sys/net/if_etherip.h | 1 | ||||
-rw-r--r-- | sys/netinet/in_proto.c | 3 | ||||
-rw-r--r-- | sys/netinet/ip_ether.c | 76 | ||||
-rw-r--r-- | sys/netinet/ip_ether.h | 44 |
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, - ðeripstat, 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, - ðeripstat, 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(ðeripstat, 0, sizeof etheripstat); + counters_read(etheripcounters, (uint64_t *)ðeripstat, + etherips_ncounters); + return (sysctl_rdstruct(oldp, oldlenp, newp, ðeripstat, + 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_ */ |