From b25d74e06c0c15679da0de6ec4a0fac32e9e917f Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Sat, 9 Mar 2019 01:12:59 +0000 Subject: [PATCH] Improve ARP logging. r344504 added an extra ARP_LOG() call in case of an if_output() failure. It turns out IPv4 can be noisy. In order to not spam the console by default: (a) add a counter for these events so people can keep better track of how often it happens, and (b) add a sysctl to select the default ARP_LOG log level and set it to INFO avoiding the one (the new) DEBUG level by default. Claim a spare (1st one after 10 years since the stats were added) in order to not break netstat from FreeBSD 12->13 updates in the future. Reviewed by: karels Differential Revision: https://reviews.freebsd.org/D19490 --- sys/net/if_arp.h | 3 ++- sys/netinet/if_ether.c | 13 +++++++++++-- usr.bin/netstat/inet.c | 1 + 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/sys/net/if_arp.h b/sys/net/if_arp.h index 070dbafe10f0..f4c3bec217d4 100644 --- a/sys/net/if_arp.h +++ b/sys/net/if_arp.h @@ -105,8 +105,9 @@ struct arpstat { uint64_t rxrequests; /* # of ARP requests received by this host. */ uint64_t rxreplies; /* # of ARP replies received by this host. */ uint64_t received; /* # of ARP packets received by this host. */ + uint64_t txerrors; /* # of ARP requests failed to send. */ - uint64_t arp_spares[4]; /* For either the upper or lower half. */ + uint64_t arp_spares[3]; /* For either the upper or lower half. */ /* Abnormal event and error counting: */ uint64_t dropped; /* # of packets dropped waiting for a reply. */ uint64_t timeouts; /* # of times with entries removed */ diff --git a/sys/netinet/if_ether.c b/sys/netinet/if_ether.c index 5cf774a5d7c7..a623d2bb0dde 100644 --- a/sys/netinet/if_ether.c +++ b/sys/netinet/if_ether.c @@ -161,8 +161,15 @@ SYSCTL_PROC(_net_link_ether_inet, OID_AUTO, garp_rexmit_count, "Number of times to retransmit GARP packets;" " 0 to disable, maximum of 16"); +VNET_DEFINE_STATIC(int, arp_log_level) = LOG_INFO; /* Min. log(9) level. */ +#define V_arp_log_level VNET(arp_log_level) +SYSCTL_INT(_net_link_ether_arp, OID_AUTO, log_level, CTLFLAG_VNET | CTLFLAG_RW, + &VNET_NAME(arp_log_level), 0, + "Minimum log(9) level for recording rate limited arp log messages. " + "The higher will be log more (emerg=0, info=6 (default), debug=7)."); #define ARP_LOG(pri, ...) do { \ - if (ppsratecheck(&arp_lastlog, &arp_curpps, arp_maxpps)) \ + if ((pri) <= V_arp_log_level && \ + ppsratecheck(&arp_lastlog, &arp_curpps, arp_maxpps)) \ log((pri), "arp: " __VA_ARGS__); \ } while (0) @@ -428,9 +435,11 @@ arprequest_internal(struct ifnet *ifp, const struct in_addr *sip, m_clrprotoflags(m); /* Avoid confusing lower layers. */ error = (*ifp->if_output)(ifp, m, &sa, &ro); ARPSTAT_INC(txrequests); - if (error) + if (error) { + ARPSTAT_INC(txerrors); ARP_LOG(LOG_DEBUG, "Failed to send ARP packet on %s: %d\n", if_name(ifp), error); + } return (error); } diff --git a/usr.bin/netstat/inet.c b/usr.bin/netstat/inet.c index 67a74300b817..dfb33b02784b 100644 --- a/usr.bin/netstat/inet.c +++ b/usr.bin/netstat/inet.c @@ -1044,6 +1044,7 @@ arp_stats(u_long off, const char *name, int af1 __unused, int proto __unused) xo_emit("\t" m, (uintmax_t)arpstat.f, pluralies(arpstat.f)) p(txrequests, "{:sent-requests/%ju} {N:/ARP request%s sent}\n"); + p(txerrors, "{:sent-failures/%ju} {N:/ARP request%s failed to sent}\n"); p2(txreplies, "{:sent-replies/%ju} {N:/ARP repl%s sent}\n"); p(rxrequests, "{:received-requests/%ju} " "{N:/ARP request%s received}\n");