diff options
author | 2017-01-04 04:56:24 +0000 | |
---|---|---|
committer | 2017-01-04 04:56:24 +0000 | |
commit | 4fc2f7f95ff1257b483a6d30e53fd125113e9187 (patch) | |
tree | eb78aafe02384e74586b751979763902307d2ef7 | |
parent | dont assume setting IFF_UP will succeed. (diff) | |
download | wireguard-openbsd-4fc2f7f95ff1257b483a6d30e53fd125113e9187.tar.xz wireguard-openbsd-4fc2f7f95ff1257b483a6d30e53fd125113e9187.zip |
convert igmp_stat into per-cpu counters
it follows the same pattern used in previous conversions.
from Dimitris Papastamos (thank you).
ok mpi@
-rw-r--r-- | sys/netinet/igmp.c | 56 | ||||
-rw-r--r-- | sys/netinet/igmp_var.h | 26 |
2 files changed, 62 insertions, 20 deletions
diff --git a/sys/netinet/igmp.c b/sys/netinet/igmp.c index f1b142c093c..c59d03038c1 100644 --- a/sys/netinet/igmp.c +++ b/sys/netinet/igmp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: igmp.c,v 1.59 2016/12/19 09:22:24 rzalamena Exp $ */ +/* $OpenBSD: igmp.c,v 1.60 2017/01/04 04:56:24 dlg Exp $ */ /* $NetBSD: igmp.c,v 1.15 1996/02/13 23:41:25 christos Exp $ */ /* @@ -101,13 +101,14 @@ int *igmpctl_vars[IGMPCTL_MAXID] = IGMPCTL_VARS; int igmp_timers_are_running; static struct router_info *rti_head; static struct mbuf *router_alert; -struct igmpstat igmpstat; +struct cpumem *igmpcounters; void igmp_checktimer(struct ifnet *); void igmp_sendpkt(struct ifnet *, struct in_multi *, int, in_addr_t); int rti_fill(struct in_multi *); struct router_info * rti_find(struct ifnet *); void igmp_input_if(struct ifnet *, struct mbuf *, int); +int igmp_sysctl_igmpstat(void *, size_t *, void *); void igmp_init(void) @@ -117,6 +118,7 @@ igmp_init(void) igmp_timers_are_running = 0; rti_head = 0; + igmpcounters = counters_alloc(igps_ncounters, M_COUNTERS); router_alert = m_get(M_DONTWAIT, MT_DATA); if (router_alert == NULL) { printf("%s: no mbuf\n", __func__); @@ -217,7 +219,7 @@ igmp_input(struct mbuf *m, ...) iphlen = va_arg(ap, int); va_end(ap); - ++igmpstat.igps_rcv_total; + igmpstat_inc(igps_rcv_total); ifp = if_get(m->m_pkthdr.ph_ifidx); if (ifp == NULL) { @@ -248,14 +250,14 @@ igmp_input_if(struct ifnet *ifp, struct mbuf *m, int iphlen) * Validate lengths */ if (igmplen < IGMP_MINLEN) { - ++igmpstat.igps_rcv_tooshort; + igmpstat_inc(igps_rcv_tooshort); m_freem(m); return; } minlen = iphlen + IGMP_MINLEN; if ((m->m_flags & M_EXT || m->m_len < minlen) && (m = m_pullup(m, minlen)) == NULL) { - ++igmpstat.igps_rcv_tooshort; + igmpstat_inc(igps_rcv_tooshort); return; } @@ -266,7 +268,7 @@ igmp_input_if(struct ifnet *ifp, struct mbuf *m, int iphlen) m->m_len -= iphlen; igmp = mtod(m, struct igmp *); if (in_cksum(m, igmplen)) { - ++igmpstat.igps_rcv_badsum; + igmpstat_inc(igps_rcv_badsum); m_freem(m); return; } @@ -277,7 +279,7 @@ igmp_input_if(struct ifnet *ifp, struct mbuf *m, int iphlen) switch (igmp->igmp_type) { case IGMP_HOST_MEMBERSHIP_QUERY: - ++igmpstat.igps_rcv_queries; + igmpstat_inc(igps_rcv_queries); if (ifp->if_flags & IFF_LOOPBACK) break; @@ -292,7 +294,7 @@ igmp_input_if(struct ifnet *ifp, struct mbuf *m, int iphlen) rti->rti_age = 0; if (ip->ip_dst.s_addr != INADDR_ALLHOSTS_GROUP) { - ++igmpstat.igps_rcv_badqueries; + igmpstat_inc(igps_rcv_badqueries); m_freem(m); return; } @@ -317,7 +319,7 @@ igmp_input_if(struct ifnet *ifp, struct mbuf *m, int iphlen) } } else { if (!IN_MULTICAST(ip->ip_dst.s_addr)) { - ++igmpstat.igps_rcv_badqueries; + igmpstat_inc(igps_rcv_badqueries); m_freem(m); return; } @@ -367,14 +369,14 @@ igmp_input_if(struct ifnet *ifp, struct mbuf *m, int iphlen) break; case IGMP_v1_HOST_MEMBERSHIP_REPORT: - ++igmpstat.igps_rcv_reports; + igmpstat_inc(igps_rcv_reports); if (ifp->if_flags & IFF_LOOPBACK) break; if (!IN_MULTICAST(igmp->igmp_group.s_addr) || igmp->igmp_group.s_addr != ip->ip_dst.s_addr) { - ++igmpstat.igps_rcv_badreports; + igmpstat_inc(igps_rcv_badreports); m_freem(m); return; } @@ -401,7 +403,7 @@ igmp_input_if(struct ifnet *ifp, struct mbuf *m, int iphlen) IN_LOOKUP_MULTI(igmp->igmp_group, ifp, inm); if (inm != NULL) { inm->inm_timer = 0; - ++igmpstat.igps_rcv_ourreports; + igmpstat_inc(igps_rcv_ourreports); switch (inm->inm_state) { case IGMP_IDLE_MEMBER: @@ -433,14 +435,14 @@ igmp_input_if(struct ifnet *ifp, struct mbuf *m, int iphlen) break; #endif - ++igmpstat.igps_rcv_reports; + igmpstat_inc(igps_rcv_reports); if (ifp->if_flags & IFF_LOOPBACK) break; if (!IN_MULTICAST(igmp->igmp_group.s_addr) || igmp->igmp_group.s_addr != ip->ip_dst.s_addr) { - ++igmpstat.igps_rcv_badreports; + igmpstat_inc(igps_rcv_badreports); m_freem(m); return; } @@ -469,7 +471,7 @@ igmp_input_if(struct ifnet *ifp, struct mbuf *m, int iphlen) IN_LOOKUP_MULTI(igmp->igmp_group, ifp, inm); if (inm != NULL) { inm->inm_timer = 0; - ++igmpstat.igps_rcv_ourreports; + igmpstat_inc(igps_rcv_ourreports); switch (inm->inm_state) { case IGMP_DELAYING_MEMBER: @@ -671,7 +673,7 @@ igmp_sendpkt(struct ifnet *ifp, struct in_multi *inm, int type, ip_output(m, router_alert, NULL, IP_MULTICASTOPTS, &imo, NULL, 0); - ++igmpstat.igps_snd_reports; + igmpstat_inc(igps_snd_reports); } /* @@ -689,8 +691,7 @@ igmp_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, case IGMPCTL_STATS: if (newp != NULL) return (EPERM); - return (sysctl_struct(oldp, oldlenp, newp, newlen, - &igmpstat, sizeof(igmpstat))); + return (igmp_sysctl_igmpstat(oldp, oldlenp, newp)); default: if (name[0] < IGMPCTL_MAXID) return (sysctl_int_arr(igmpctl_vars, name, namelen, @@ -699,3 +700,22 @@ igmp_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, } /* NOTREACHED */ } + +int +igmp_sysctl_igmpstat(void *oldp, size_t *oldlenp, void *newp) +{ + uint64_t counters[igps_ncounters]; + struct igmpstat igmpstat; + u_long *words = (u_long *)&igmpstat; + int i; + + KASSERT(sizeof(igmpstat) == (nitems(counters) * sizeof(u_long))); + + counters_read(igmpcounters, counters, nitems(counters)); + + for (i = 0; i < nitems(counters); i++) + words[i] = (u_long)counters[i]; + + return (sysctl_rdstruct(oldp, oldlenp, newp, + &igmpstat, sizeof(igmpstat))); +} diff --git a/sys/netinet/igmp_var.h b/sys/netinet/igmp_var.h index ea066093ec4..091022c8110 100644 --- a/sys/netinet/igmp_var.h +++ b/sys/netinet/igmp_var.h @@ -1,4 +1,4 @@ -/* $OpenBSD: igmp_var.h,v 1.9 2008/04/18 06:42:20 djm Exp $ */ +/* $OpenBSD: igmp_var.h,v 1.10 2017/01/04 04:56:24 dlg Exp $ */ /* $NetBSD: igmp_var.h,v 1.9 1996/02/13 23:41:31 christos Exp $ */ /* @@ -78,7 +78,29 @@ struct igmpstat { } #ifdef _KERNEL -extern struct igmpstat igmpstat; + +#include <sys/percpu.h> + +enum igmpstat_counters { + igps_rcv_total, /* total IGMP messages received */ + igps_rcv_tooshort, /* received with too few bytes */ + igps_rcv_badsum, /* received with bad checksum */ + igps_rcv_queries, /* received membership queries */ + igps_rcv_badqueries, /* received invalid queries */ + igps_rcv_reports, /* received membership reports */ + igps_rcv_badreports, /* received invalid reports */ + igps_rcv_ourreports, /* received reports for our groups */ + igps_snd_reports, /* sent membership reports */ + igps_ncounters +}; + +extern struct cpumem *igmpcounters; + +static inline void +igmpstat_inc(enum igmpstat_counters c) +{ + counters_inc(igmpcounters, c); +} /* * Macro to compute a random timer value between 1 and (IGMP_MAX_REPORTING_ |