Date: Thu, 28 Jan 2010 16:48:44 +0000 (UTC) From: "George V. Neville-Neil" <gnn@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org Subject: svn commit: r203120 - in stable/8: sys/net sys/netinet usr.bin/netstat Message-ID: <201001281648.o0SGmi9p095908@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: gnn Date: Thu Jan 28 16:48:44 2010 New Revision: 203120 URL: http://svn.freebsd.org/changeset/base/203120 Log: MFC r196797: Add ARP statistics to the kernel and netstat. Modified: stable/8/sys/net/if_arp.h stable/8/sys/netinet/if_ether.c stable/8/usr.bin/netstat/inet.c stable/8/usr.bin/netstat/main.c stable/8/usr.bin/netstat/netstat.h Directory Properties: stable/8/sys/ (props changed) stable/8/sys/amd64/include/xen/ (props changed) stable/8/sys/cddl/contrib/opensolaris/ (props changed) stable/8/sys/contrib/dev/acpica/ (props changed) stable/8/sys/contrib/pf/ (props changed) stable/8/sys/dev/xen/xenpci/ (props changed) stable/8/usr.bin/netstat/ (props changed) Modified: stable/8/sys/net/if_arp.h ============================================================================== --- stable/8/sys/net/if_arp.h Thu Jan 28 16:17:24 2010 (r203119) +++ stable/8/sys/net/if_arp.h Thu Jan 28 16:48:44 2010 (r203120) @@ -108,6 +108,31 @@ struct arpcom { #define IFP2AC(ifp) ((struct arpcom *)(ifp->if_l2com)) #define AC2IFP(ac) ((ac)->ac_ifp) -#endif +#endif /* _KERNEL */ + +struct arpstat { + /* Normal things that happen: */ + u_long txrequests; /* # of ARP requests sent by this host. */ + u_long txreplies; /* # of ARP replies sent by this host. */ + u_long rxrequests; /* # of ARP requests received by this host. */ + u_long rxreplies; /* # of ARP replies received by this host. */ + u_long received; /* # of ARP packets received by this host. */ + + u_long arp_spares[4]; /* For either the upper or lower half. */ + /* Abnormal event and error counting: */ + u_long dropped; /* # of packets dropped waiting for a reply. */ + u_long timeouts; /* # of times with entries removed */ + /* due to timeout. */ + u_long dupips; /* # of duplicate IPs detected. */ +}; + +/* + * In-kernel consumers can use these accessor macros directly to update + * stats. + */ +#define ARPSTAT_ADD(name, val) V_arpstat.name += (val) +#define ARPSTAT_SUB(name, val) V_arpstat.name -= (val) +#define ARPSTAT_INC(name) ARPSTAT_ADD(name, 1) +#define ARPSTAT_DEC(name) ARPSTAT_SUB(name, 1) #endif /* !_NET_IF_ARP_H_ */ Modified: stable/8/sys/netinet/if_ether.c ============================================================================== --- stable/8/sys/netinet/if_ether.c Thu Jan 28 16:17:24 2010 (r203119) +++ stable/8/sys/netinet/if_ether.c Thu Jan 28 16:48:44 2010 (r203120) @@ -80,6 +80,7 @@ __FBSDID("$FreeBSD$"); SYSCTL_DECL(_net_link_ether); SYSCTL_NODE(_net_link_ether, PF_INET, inet, CTLFLAG_RW, 0, ""); +SYSCTL_NODE(_net_link_ether, PF_ARP, arp, CTLFLAG_RW, 0, ""); VNET_DEFINE(int, useloopback) = 1; /* use loopback interface for * local traffic */ @@ -91,11 +92,13 @@ static VNET_DEFINE(int, arpt_down) = 20; * 20 seconds */ static VNET_DEFINE(int, arp_maxtries) = 5; static VNET_DEFINE(int, arp_proxyall); +static VNET_DEFINE(struct arpstat, arpstat); /* ARP statistics, see if_arp.h */ #define V_arpt_keep VNET(arpt_keep) #define V_arpt_down VNET(arpt_down) #define V_arp_maxtries VNET(arp_maxtries) #define V_arp_proxyall VNET(arp_proxyall) +#define V_arpstat VNET(arpstat) SYSCTL_VNET_INT(_net_link_ether_inet, OID_AUTO, max_age, CTLFLAG_RW, &VNET_NAME(arpt_keep), 0, @@ -110,6 +113,9 @@ SYSCTL_VNET_INT(_net_link_ether_inet, OI SYSCTL_VNET_INT(_net_link_ether_inet, OID_AUTO, proxyall, CTLFLAG_RW, &VNET_NAME(arp_proxyall), 0, "Enable proxy ARP for all suitable requests"); +SYSCTL_VNET_STRUCT(_net_link_ether_arp, OID_AUTO, stats, CTLFLAG_RW, + &VNET_NAME(arpstat), arpstat, + "ARP statistics (struct arpstat, net/if_arp.h)"); static void arp_init(void); void arprequest(struct ifnet *, @@ -166,6 +172,7 @@ arptimer(void *arg) return; } ifp = lle->lle_tbl->llt_ifp; + CURVNET_SET(ifp->if_vnet); IF_AFDATA_LOCK(ifp); LLE_WLOCK(lle); if (lle->la_flags & LLE_STATIC) @@ -174,6 +181,7 @@ arptimer(void *arg) if (!callout_pending(&lle->la_timer) && callout_active(&lle->la_timer)) { (void) llentry_free(lle); + ARPSTAT_INC(timeouts); } #ifdef DIAGNOSTIC else { @@ -186,6 +194,7 @@ arptimer(void *arg) #endif } IF_AFDATA_UNLOCK(ifp); + CURVNET_RESTORE(); } /* @@ -247,6 +256,7 @@ arprequest(struct ifnet *ifp, struct in_ sa.sa_len = 2; m->m_flags |= M_BCAST; (*ifp->if_output)(ifp, m, &sa, NULL); + ARPSTAT_INC(txrequests); } /* @@ -348,8 +358,10 @@ retry: * latest one. */ if (m != NULL) { - if (la->la_hold != NULL) + if (la->la_hold != NULL) { m_freem(la->la_hold); + ARPSTAT_INC(dropped); + } la->la_hold = m; if (renew == 0 && (flags & LLE_EXCLUSIVE)) { flags &= ~LLE_EXCLUSIVE; @@ -422,6 +434,7 @@ arpintr(struct mbuf *m) ar = mtod(m, struct arphdr *); } + ARPSTAT_INC(received); switch (ntohs(ar->ar_pro)) { #ifdef INET case ETHERTYPE_IP: @@ -502,6 +515,9 @@ in_arpinput(struct mbuf *m) (void)memcpy(&isaddr, ar_spa(ah), sizeof (isaddr)); (void)memcpy(&itaddr, ar_tpa(ah), sizeof (itaddr)); + if (op == ARPOP_REPLY) + ARPSTAT_INC(rxreplies); + /* * For a bridge, we want to check the address irrespective * of the receive interface. (This will change slightly @@ -612,6 +628,7 @@ match: ifp->if_addrlen, (u_char *)ar_sha(ah), ":", inet_ntoa(isaddr), ifp->if_xname); itaddr = myaddr; + ARPSTAT_INC(dupips); goto reply; } if (ifp->if_flags & IFF_STATICARP) @@ -695,6 +712,7 @@ match: reply: if (op != ARPOP_REQUEST) goto drop; + ARPSTAT_INC(rxrequests); if (itaddr.s_addr == myaddr.s_addr) { /* Shortcut.. the receiving interface is the target. */ @@ -791,6 +809,7 @@ reply: sa.sa_family = AF_ARP; sa.sa_len = 2; (*ifp->if_output)(ifp, m, &sa, NULL); + ARPSTAT_INC(txreplies); return; drop: Modified: stable/8/usr.bin/netstat/inet.c ============================================================================== --- stable/8/usr.bin/netstat/inet.c Thu Jan 28 16:17:24 2010 (r203119) +++ stable/8/usr.bin/netstat/inet.c Thu Jan 28 16:48:44 2010 (r203120) @@ -49,6 +49,7 @@ __FBSDID("$FreeBSD$"); #include <sys/sysctl.h> #include <net/route.h> +#include <net/if_arp.h> #include <netinet/in.h> #include <netinet/in_systm.h> #include <netinet/ip.h> @@ -871,6 +872,47 @@ ip_stats(u_long off, const char *name, i #undef p1a } +/* + * Dump ARP statistics structure. + */ +void +arp_stats(u_long off, const char *name, int af1 __unused, int proto __unused) +{ + struct arpstat arpstat, zerostat; + size_t len = sizeof(arpstat); + + if (live) { + if (zflag) + memset(&zerostat, 0, len); + if (sysctlbyname("net.link.ether.arp.stats", &arpstat, &len, + zflag ? &zerostat : NULL, zflag ? len : 0) < 0) { + warn("sysctl: net.link.ether.arp.stats"); + return; + } + } else + kread(off, &arpstat, len); + + printf("%s:\n", name); + +#define p(f, m) if (arpstat.f || sflag <= 1) \ + printf(m, arpstat.f, plural(arpstat.f)) +#define p2(f, m) if (arpstat.f || sflag <= 1) \ + printf(m, arpstat.f, pluralies(arpstat.f)) + + p(txrequests, "\t%lu ARP request%s sent\n"); + p2(txreplies, "\t%lu ARP repl%s sent\n"); + p(rxrequests, "\t%lu ARP request%s received\n"); + p2(rxreplies, "\t%lu ARP repl%s received\n"); + p(received, "\t%lu ARP packet%s received\n"); + p(dropped, "\t%lu total packet%s dropped due to no ARP entry\n"); + p(timeouts, "\t%lu ARP entry%s timed out\n"); + p(dupips, "\t%lu Duplicate IP%s seen\n"); +#undef p +#undef p2 +} + + + static const char *icmpnames[ICMP_MAXTYPE + 1] = { "echo reply", /* RFC 792 */ "#1", Modified: stable/8/usr.bin/netstat/main.c ============================================================================== --- stable/8/usr.bin/netstat/main.c Thu Jan 28 16:17:24 2010 (r203119) +++ stable/8/usr.bin/netstat/main.c Thu Jan 28 16:48:44 2010 (r203120) @@ -184,6 +184,8 @@ static struct nlist nl[] = { { .n_name = "_sctpstat" }, #define N_MFCTABLESIZE 54 { .n_name = "_mfctablesize" }, +#define N_ARPSTAT 55 + { .n_name = "_arpstat" }, { .n_name = NULL }, }; @@ -232,6 +234,8 @@ struct protox { carp_stats, NULL, "carp", 1, 0 }, { -1, N_PFSYNCSTAT, 1, NULL, pfsync_stats, NULL, "pfsync", 1, 0 }, + { -1, N_ARPSTAT, 1, NULL, + arp_stats, NULL, "arp", 1, 0 }, { -1, -1, 0, NULL, NULL, NULL, NULL, 0, 0 } }; Modified: stable/8/usr.bin/netstat/netstat.h ============================================================================== --- stable/8/usr.bin/netstat/netstat.h Thu Jan 28 16:17:24 2010 (r203119) +++ stable/8/usr.bin/netstat/netstat.h Thu Jan 28 16:48:44 2010 (r203120) @@ -75,6 +75,7 @@ void udp_stats(u_long, const char *, int void sctp_protopr(u_long, const char *, int, int); void sctp_stats(u_long, const char *, int, int); #endif +void arp_stats(u_long, const char *, int, int); void ip_stats(u_long, const char *, int, int); void icmp_stats(u_long, const char *, int, int); void igmp_stats(u_long, const char *, int, int);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201001281648.o0SGmi9p095908>