summaryrefslogtreecommitdiffstats
path: root/sys/netinet/if_ether.c
diff options
context:
space:
mode:
authorgnn <gnn@FreeBSD.org>2009-09-03 21:10:57 +0000
committergnn <gnn@FreeBSD.org>2009-09-03 21:10:57 +0000
commit60eb51e7a3e3a1dfacd9d9284b7e21e1fe4de011 (patch)
treeadac442cdf92025f0d2ded02f1a96f79bc1b1cfc /sys/netinet/if_ether.c
parent5d151fa1f9e0bab1181b49200884097a9b1874ac (diff)
downloadFreeBSD-src-60eb51e7a3e3a1dfacd9d9284b7e21e1fe4de011.zip
FreeBSD-src-60eb51e7a3e3a1dfacd9d9284b7e21e1fe4de011.tar.gz
Add ARP statistics to the kernel and netstat.
New counters now exist for: requests sent replies sent requests received replies received packets received total packets dropped due to no ARP entry entrys timed out Duplicate IPs seen The new statistics are seen in the netstat command when it is given the -s command line switch. MFC after: 2 weeks In collaboration with: bz
Diffstat (limited to 'sys/netinet/if_ether.c')
-rw-r--r--sys/netinet/if_ether.c31
1 files changed, 25 insertions, 6 deletions
diff --git a/sys/netinet/if_ether.c b/sys/netinet/if_ether.c
index e118cec..c170c7a 100644
--- a/sys/netinet/if_ether.c
+++ b/sys/netinet/if_ether.c
@@ -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 */
@@ -89,10 +90,12 @@ static VNET_DEFINE(int, arpt_keep) = (20*60); /* once resolved, good for 20
* minutes */
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_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,
@@ -107,6 +110,9 @@ SYSCTL_VNET_INT(_net_link_ether_inet, OID_AUTO, useloopback, CTLFLAG_RW,
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 *,
@@ -163,20 +169,23 @@ 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_DELETED)
- || (time_second >= lle->la_expire))
- && (!callout_pending(&lle->la_timer) &&
- callout_active(&lle->la_timer)))
+ if (((lle->la_flags & LLE_DELETED) ||
+ (time_second >= lle->la_expire)) &&
+ (!callout_pending(&lle->la_timer) &&
+ callout_active(&lle->la_timer))) {
(void) llentry_free(lle);
- else {
+ ARPSTAT_INC(timeouts);
+ } else {
/*
* Still valid, just drop our reference
*/
LLE_FREE_LOCKED(lle);
}
IF_AFDATA_UNLOCK(ifp);
+ CURVNET_RESTORE();
}
/*
@@ -238,6 +247,7 @@ arprequest(struct ifnet *ifp, struct in_addr *sip, struct in_addr *tip,
sa.sa_len = 2;
m->m_flags |= M_BCAST;
(*ifp->if_output)(ifp, m, &sa, NULL);
+ ARPSTAT_INC(txrequests);
}
/*
@@ -339,8 +349,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;
@@ -413,6 +425,7 @@ arpintr(struct mbuf *m)
ar = mtod(m, struct arphdr *);
}
+ ARPSTAT_INC(received);
switch (ntohs(ar->ar_pro)) {
#ifdef INET
case ETHERTYPE_IP:
@@ -493,6 +506,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
@@ -603,6 +619,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)
@@ -686,6 +703,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. */
@@ -774,6 +792,7 @@ reply:
sa.sa_family = AF_ARP;
sa.sa_len = 2;
(*ifp->if_output)(ifp, m, &sa, NULL);
+ ARPSTAT_INC(txreplies);
return;
drop:
OpenPOWER on IntegriCloud