diff --git a/sys/netatalk/ddp_input.c b/sys/netatalk/ddp_input.c index 062e3d030f74..313b9b896cdb 100644 --- a/sys/netatalk/ddp_input.c +++ b/sys/netatalk/ddp_input.c @@ -1,4 +1,4 @@ -/* $NetBSD: ddp_input.c,v 1.17 2007/12/21 02:46:37 dyoung Exp $ */ +/* $NetBSD: ddp_input.c,v 1.18 2008/04/23 15:17:42 thorpej Exp $ */ /* * Copyright (c) 1990,1994 Regents of The University of Michigan. @@ -27,7 +27,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ddp_input.c,v 1.17 2007/12/21 02:46:37 dyoung Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ddp_input.c,v 1.18 2008/04/23 15:17:42 thorpej Exp $"); #include #include @@ -46,6 +46,7 @@ __KERNEL_RCSID(0, "$NetBSD: ddp_input.c,v 1.17 2007/12/21 02:46:37 dyoung Exp $" #include #include #include +#include #include int ddp_forward = 1; @@ -113,7 +114,7 @@ atintr() } if (m->m_len < SZ_ELAPHDR && ((m = m_pullup(m, SZ_ELAPHDR)) == 0)) { - ddpstat.ddps_tooshort++; + DDP_STATINC(DDP_STAT_TOOSHORT); continue; } elhp = mtod(m, struct elaphdr *); @@ -152,11 +153,11 @@ ddp_input(m, ifp, elh, phase) bzero((void *) & from, sizeof(struct sockaddr_at)); if (elh) { - ddpstat.ddps_short++; + DDP_STATINC(DDP_STAT_SHORT); if (m->m_len < sizeof(struct ddpshdr) && ((m = m_pullup(m, sizeof(struct ddpshdr))) == 0)) { - ddpstat.ddps_tooshort++; + DDP_STATINC(DDP_STAT_TOOSHORT); return; } dsh = mtod(m, struct ddpshdr *); @@ -184,11 +185,11 @@ ddp_input(m, ifp, elh, phase) return; } } else { - ddpstat.ddps_long++; + DDP_STATINC(DDP_STAT_LONG); if (m->m_len < sizeof(struct ddpehdr) && ((m = m_pullup(m, sizeof(struct ddpehdr))) == 0)) { - ddpstat.ddps_tooshort++; + DDP_STATINC(DDP_STAT_TOOSHORT); return; } deh = mtod(m, struct ddpehdr *); @@ -197,7 +198,7 @@ ddp_input(m, ifp, elh, phase) dlen = ddpe.deh_len; if ((cksum = ddpe.deh_sum) == 0) { - ddpstat.ddps_nosum++; + DDP_STATINC(DDP_STAT_NOSUM); } from.sat_addr.s_net = ddpe.deh_snet; from.sat_addr.s_node = ddpe.deh_snode; @@ -255,7 +256,7 @@ ddp_input(m, ifp, elh, phase) */ mlen = m->m_pkthdr.len; if (mlen < dlen) { - ddpstat.ddps_toosmall++; + DDP_STATINC(DDP_STAT_TOOSMALL); m_freem(m); return; } @@ -292,9 +293,9 @@ ddp_input(m, ifp, elh, phase) ddpe.deh_bytes = htonl(ddpe.deh_bytes); bcopy((void *) & ddpe, (void *) deh, sizeof(u_short));/*XXX*/ if (ddp_route(m, &forwro)) { - ddpstat.ddps_cantforward++; + DDP_STATINC(DDP_STAT_CANTFORWARD); } else { - ddpstat.ddps_forward++; + DDP_STATINC(DDP_STAT_FORWARD); } return; } @@ -305,7 +306,7 @@ ddp_input(m, ifp, elh, phase) m_adj(m, sizeof(struct ddpshdr)); } else { if (ddp_cksum && cksum && cksum != at_cksum(m, sizeof(int))) { - ddpstat.ddps_badsum++; + DDP_STATINC(DDP_STAT_BADSUM); m_freem(m); return; } @@ -318,7 +319,7 @@ ddp_input(m, ifp, elh, phase) } if (sbappendaddr(&ddp->ddp_socket->so_rcv, (struct sockaddr *) & from, m, (struct mbuf *) 0) == 0) { - ddpstat.ddps_nosockspace++; + DDP_STATINC(DDP_STAT_NOSOCKSPACE); m_freem(m); return; } diff --git a/sys/netatalk/ddp_private.h b/sys/netatalk/ddp_private.h new file mode 100644 index 000000000000..4f226568b636 --- /dev/null +++ b/sys/netatalk/ddp_private.h @@ -0,0 +1,50 @@ +/* $NetBSD: ddp_private.h,v 1.1 2008/04/23 15:24:14 thorpej Exp $ */ + +/*- + * Copyright (c) 2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Jason R. Thorpe. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _NETATALK_DDP_PRIVATE_H_ +#define _NETATALK_DDP_PRIVATE_H_ + +#ifdef _KERNEL +#include + +extern percpu_t *ddpstat_percpu; + +#define DDP_STATINC(x) _NET_STATINC(ddpstat_percpu, x) +#endif /* _KERNEL */ + +#endif /* !_NETATALK_DDP_PRIVATE_H_ */ diff --git a/sys/netatalk/ddp_usrreq.c b/sys/netatalk/ddp_usrreq.c index ee827bb5c12e..f42af1934312 100644 --- a/sys/netatalk/ddp_usrreq.c +++ b/sys/netatalk/ddp_usrreq.c @@ -1,4 +1,4 @@ -/* $NetBSD: ddp_usrreq.c,v 1.30 2008/01/28 18:28:31 dyoung Exp $ */ +/* $NetBSD: ddp_usrreq.c,v 1.31 2008/04/23 15:17:42 thorpej Exp $ */ /* * Copyright (c) 1990,1991 Regents of The University of Michigan. @@ -27,7 +27,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ddp_usrreq.c,v 1.30 2008/01/28 18:28:31 dyoung Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ddp_usrreq.c,v 1.31 2008/04/23 15:17:42 thorpej Exp $"); #include "opt_mbuftrace.h" @@ -42,14 +42,17 @@ __KERNEL_RCSID(0, "$NetBSD: ddp_usrreq.c,v 1.30 2008/01/28 18:28:31 dyoung Exp $ #include #include #include +#include #include #include #include +#include #include #include #include #include +#include #include #include @@ -63,7 +66,7 @@ static int at_pcballoc __P((struct socket *)); struct ifqueue atintrq1, atintrq2; struct ddpcb *ddp_ports[ATPORT_LAST]; struct ddpcb *ddpcb = NULL; -struct ddpstat ddpstat; +percpu_t *ddpstat_percpu; struct at_ifaddrhead at_ifaddr; /* Here as inited in this file */ u_long ddp_sendspace = DDP_MAXSZ; /* Max ddp size + 1 (ddp_type) */ u_long ddp_recvspace = 25 * (587 + sizeof(struct sockaddr_at)); @@ -550,8 +553,11 @@ ddp_search( * Initialize all the ddp & appletalk stuff */ void -ddp_init() +ddp_init(void) { + + ddpstat_percpu = percpu_alloc(sizeof(uint64_t) * DDP_NSTATS); + TAILQ_INIT(&at_ifaddr); atintrq1.ifq_maxlen = IFQ_MAXLEN; atintrq2.ifq_maxlen = IFQ_MAXLEN; @@ -570,3 +576,47 @@ ddp_clean() at_pcbdetach(ddp->ddp_socket, ddp); } #endif + +static int +sysctl_net_atalk_ddp_stats(SYSCTLFN_ARGS) +{ + netstat_sysctl_context ctx; + uint64_t ddps[DDP_NSTATS]; + + ctx.ctx_stat = ddpstat_percpu; + ctx.ctx_counters = ddps; + ctx.ctx_ncounters = DDP_NSTATS; + return (NETSTAT_SYSCTL(&ctx)); +} + +/* + * Sysctl for DDP variables. + */ +SYSCTL_SETUP(sysctl_net_atalk_ddp_setup, "sysctl net.atalk.ddp subtree setup") +{ + + sysctl_createv(clog, 0, NULL, NULL, + CTLFLAG_PERMANENT, + CTLTYPE_NODE, "net", NULL, + NULL, 0, NULL, 0, + CTL_NET, CTL_EOL); + sysctl_createv(clog, 0, NULL, NULL, + CTLFLAG_PERMANENT, + CTLTYPE_NODE, "atalk", NULL, + NULL, 0, NULL, 0, + CTL_NET, PF_APPLETALK, CTL_EOL); + sysctl_createv(clog, 0, NULL, NULL, + CTLFLAG_PERMANENT, + CTLTYPE_NODE, "ddp", + SYSCTL_DESCR("DDP related settings"), + NULL, 0, NULL, 0, + CTL_NET, PF_APPLETALK, ATPROTO_DDP, CTL_EOL); + + sysctl_createv(clog, 0, NULL, NULL, + CTLFLAG_PERMANENT, + CTLTYPE_STRUCT, "stats", + SYSCTL_DESCR("DDP statistics"), + sysctl_net_atalk_ddp_stats, 0, NULL, 0, + CTL_NET, PF_APPLETALK, ATPROTO_DDP, CTL_CREATE, + CTL_EOL); +} diff --git a/sys/netatalk/ddp_var.h b/sys/netatalk/ddp_var.h index 5093df78e4c5..9fbd5e2e00f5 100644 --- a/sys/netatalk/ddp_var.h +++ b/sys/netatalk/ddp_var.h @@ -1,4 +1,4 @@ -/* $NetBSD: ddp_var.h,v 1.3 2005/12/10 23:29:05 elad Exp $ */ +/* $NetBSD: ddp_var.h,v 1.4 2008/04/23 15:17:42 thorpej Exp $ */ /* * Copyright (c) 1990,1994 Regents of The University of Michigan. @@ -39,23 +39,22 @@ struct ddpcb { #define sotoddpcb(so) ((struct ddpcb *)(so)->so_pcb) -struct ddpstat { - long ddps_short; /* short header packets received */ - long ddps_long; /* long header packets received */ - long ddps_nosum; /* no checksum */ - long ddps_badsum; /* bad checksum */ - long ddps_tooshort; /* packet too short */ - long ddps_toosmall; /* not enough data */ - long ddps_forward; /* packets forwarded */ - long ddps_encap; /* packets encapsulated */ - long ddps_cantforward; /* packets rcvd for unreachable dest */ - long ddps_nosockspace; /* no space in sockbuf for packet */ -}; +#define DDP_STAT_SHORT 0 /* short header packets received */ +#define DDP_STAT_LONG 1 /* long header packets received */ +#define DDP_STAT_NOSUM 2 /* no checksum */ +#define DDP_STAT_BADSUM 3 /* bad checksum */ +#define DDP_STAT_TOOSHORT 4 /* packet too short */ +#define DDP_STAT_TOOSMALL 5 /* not enough data */ +#define DDP_STAT_FORWARD 6 /* packets forwarded */ +#define DDP_STAT_ENCAP 7 /* packets encapsulated */ +#define DDP_STAT_CANTFORWARD 8 /* packets rcvd for unreachable net */ +#define DDP_STAT_NOSOCKSPACE 9 /* no space in sockbuf for packet */ + +#define DDP_NSTATS 10 #ifdef _KERNEL extern struct ddpcb *ddp_ports[]; extern struct ddpcb *ddpcb; -extern struct ddpstat ddpstat; #endif #endif /* !_NETATALK_DDP_VAR_H_ */ diff --git a/usr.bin/netstat/atalk.c b/usr.bin/netstat/atalk.c index f8cb66f0bf5c..9fc64a3db028 100644 --- a/usr.bin/netstat/atalk.c +++ b/usr.bin/netstat/atalk.c @@ -1,4 +1,4 @@ -/* $NetBSD: atalk.c,v 1.10 2006/04/06 18:30:31 rpaulo Exp $ */ +/* $NetBSD: atalk.c,v 1.11 2008/04/23 15:17:42 thorpej Exp $ */ /* * Copyright (c) 1983, 1988, 1993 @@ -34,7 +34,7 @@ #if 0 static char sccsid[] = "from @(#)atalk.c 1.1 (Whistle) 6/6/96"; #else -__RCSID("$NetBSD: atalk.c,v 1.10 2006/04/06 18:30:31 rpaulo Exp $"); +__RCSID("$NetBSD: atalk.c,v 1.11 2008/04/23 15:17:42 thorpej Exp $"); #endif #endif /* not lint */ @@ -44,6 +44,7 @@ __RCSID("$NetBSD: atalk.c,v 1.10 2006/04/06 18:30:31 rpaulo Exp $"); #include #include #include +#include #include #include @@ -65,11 +66,6 @@ struct socket sockb; static int first = 1; -static char *at_pr_net __P((struct sockaddr_at *, int)); -static char *at_pr_host __P((struct sockaddr_at *, int)); -static char *at_pr_range __P((struct sockaddr_at *)); -static char *at_pr_port __P((struct sockaddr_at *)); - /* * Print a summary of connections related to a Network Systems * protocol. For XXX, also give state of connection. @@ -78,9 +74,7 @@ static char *at_pr_port __P((struct sockaddr_at *)); */ static char * -at_pr_net(sat, numeric) - struct sockaddr_at *sat; - int numeric; +at_pr_net(struct sockaddr_at *sat, int numeric) { static char mybuf[50]; @@ -97,9 +91,7 @@ at_pr_net(sat, numeric) } static char * -at_pr_host(sat, numeric) - struct sockaddr_at *sat; - int numeric; +at_pr_host(struct sockaddr_at *sat, int numeric) { static char mybuf[50]; @@ -117,8 +109,7 @@ at_pr_host(sat, numeric) } static char * -at_pr_port(sat) - struct sockaddr_at *sat; +at_pr_port(struct sockaddr_at *sat) { static char mybuf[50]; @@ -135,8 +126,7 @@ at_pr_port(sat) } static char * -at_pr_range(sat) - struct sockaddr_at *sat; +at_pr_range(struct sockaddr_at *sat) { static char mybuf[50]; @@ -160,9 +150,7 @@ at_pr_range(sat) * 8 for numeric only */ char * -atalk_print(sa, what) - const struct sockaddr *sa; - int what; +atalk_print(const struct sockaddr *sa, int what) { struct sockaddr_at *sat = (struct sockaddr_at *) sa; static char mybuf[50]; @@ -197,10 +185,7 @@ atalk_print(sa, what) } char * -atalk_print2(sa, mask, what) - const struct sockaddr *sa; - const struct sockaddr *mask; - int what; +atalk_print2(const struct sockaddr *sa, const struct sockaddr *mask, int what) { int n, l; static char buf[100]; @@ -241,9 +226,7 @@ atalk_print2(sa, mask, what) } void -atalkprotopr(off, name) - u_long off; - char *name; +atalkprotopr(u_long off, char *name) { struct ddpcb cb; struct ddpcb *prev, *next; @@ -296,32 +279,40 @@ atalkprotopr(off, name) } } #define ANY(x,y,z) \ - ((sflag==1 || (x)) ? printf("\t%ld %s%s%s\n",x,y,plural(x),z) : 0) + ((sflag==1 || (x)) ? printf("\t%llu %s%s%s\n",(unsigned long long)x,y,plural(x),z) : 0) /* * Dump DDP statistics structure. */ void -ddp_stats(off, name) - u_long off; - char *name; +ddp_stats(u_long off, char *name) { - struct ddpstat ddpstat; + uint64_t ddpstat[DDP_NSTATS]; + + if (use_sysctl) { + size_t size = sizeof(ddpstat); + + if (sysctlbyname("net.at.ddp.stats", ddpstat, &size, + NULL, 0) == -1) + return; + } else { + if (off == 0) + return; + if (kread(off, (char *)&ddpstat, sizeof(ddpstat)) < 0) + return; + } - if (off == 0) - return; - if (kread(off, (char *)&ddpstat, sizeof(ddpstat)) < 0) - return; printf("%s:\n", name); - ANY(ddpstat.ddps_short, "packet", " with short headers "); - ANY(ddpstat.ddps_long, "packet", " with long headers "); - ANY(ddpstat.ddps_nosum, "packet", " with no checksum "); - ANY(ddpstat.ddps_tooshort, "packet", " too short "); - ANY(ddpstat.ddps_badsum, "packet", " with bad checksum "); - ANY(ddpstat.ddps_toosmall, "packet", " with not enough data "); - ANY(ddpstat.ddps_forward, "packet", " forwarded "); - ANY(ddpstat.ddps_encap, "packet", " encapsulated "); - ANY(ddpstat.ddps_cantforward, "packet", " rcvd for unreachable dest "); - ANY(ddpstat.ddps_nosockspace, "packet", " dropped due to no socket space "); + + ANY(ddpstat[DDP_STAT_SHORT], "packet", " with short headers "); + ANY(ddpstat[DDP_STAT_LONG], "packet", " with long headers "); + ANY(ddpstat[DDP_STAT_NOSUM], "packet", " with no checksum "); + ANY(ddpstat[DDP_STAT_TOOSHORT], "packet", " too short "); + ANY(ddpstat[DDP_STAT_BADSUM], "packet", " with bad checksum "); + ANY(ddpstat[DDP_STAT_TOOSMALL], "packet", " with not enough data "); + ANY(ddpstat[DDP_STAT_FORWARD], "packet", " forwarded "); + ANY(ddpstat[DDP_STAT_ENCAP], "packet", " encapsulated "); + ANY(ddpstat[DDP_STAT_CANTFORWARD], "packet", " rcvd for unreachable dest "); + ANY(ddpstat[DDP_STAT_NOSOCKSPACE], "packet", " dropped due to no socket space "); } #undef ANY diff --git a/usr.bin/netstat/main.c b/usr.bin/netstat/main.c index dff3359a0f96..e4b15ae34e4f 100644 --- a/usr.bin/netstat/main.c +++ b/usr.bin/netstat/main.c @@ -1,4 +1,4 @@ -/* $NetBSD: main.c,v 1.66 2008/04/23 07:29:47 thorpej Exp $ */ +/* $NetBSD: main.c,v 1.67 2008/04/23 15:17:42 thorpej Exp $ */ /* * Copyright (c) 1983, 1988, 1993 @@ -39,7 +39,7 @@ __COPYRIGHT("@(#) Copyright (c) 1983, 1988, 1993\n\ #if 0 static char sccsid[] = "from: @(#)main.c 8.4 (Berkeley) 3/1/94"; #else -__RCSID("$NetBSD: main.c,v 1.66 2008/04/23 07:29:47 thorpej Exp $"); +__RCSID("$NetBSD: main.c,v 1.67 2008/04/23 15:17:42 thorpej Exp $"); #endif #endif /* not lint */ @@ -390,7 +390,6 @@ prepare(char *nlistf, char *memf, struct protox *tp) iflag || #ifndef SMALL gflag || - (pflag && tp->pr_sindex == N_DDPSTAT) || #ifdef NS (pflag && tp->pr_sindex == N_IDPSTAT) || (pflag && tp->pr_sindex == N_SPPSTAT) ||