From 4caea9b1693cb7e80fe11286b937dc2546224d82 Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Mon, 19 Oct 2020 17:07:19 +0000 Subject: [PATCH] icmp6: Count packets dropped due to an invalid hop limit Pad the icmp6stat structure so that we can add more counters in the future without breaking compatibility again, last done in r358620. Annotate the rarely executed error paths with __predict_false while here. Reviewed by: bz, melifaro Sponsored by: NetApp, Inc. Sponsored by: Klara, Inc. Differential Revision: https://reviews.freebsd.org/D26578 --- sys/netinet/icmp6.h | 2 ++ sys/netinet6/icmp6.c | 3 ++- sys/netinet6/nd6_nbr.c | 6 ++++-- sys/netinet6/nd6_rtr.c | 6 ++++-- usr.bin/netstat/inet6.c | 2 ++ 5 files changed, 14 insertions(+), 5 deletions(-) diff --git a/sys/netinet/icmp6.h b/sys/netinet/icmp6.h index 2544fc733b08..d4fde01c7e88 100644 --- a/sys/netinet/icmp6.h +++ b/sys/netinet/icmp6.h @@ -639,6 +639,8 @@ struct icmp6stat { uint64_t icp6s_overflowprfx; /* Too many prefixes. */ uint64_t icp6s_overflownndp; /* Too many neighbour entries. */ uint64_t icp6s_overflowredirect;/* Too many redirects. */ + uint64_t icp6s_invlhlim; /* Invalid hop limit. */ + uint64_t icp6s_spare[32]; }; #ifdef _KERNEL diff --git a/sys/netinet6/icmp6.c b/sys/netinet6/icmp6.c index 356f27f31c0f..51a20473ecd3 100644 --- a/sys/netinet6/icmp6.c +++ b/sys/netinet6/icmp6.c @@ -2261,7 +2261,8 @@ icmp6_redirect_input(struct mbuf *m, int off) ip6_sprintf(ip6buf, &src6))); goto bad; } - if (ip6->ip6_hlim != 255) { + if (__predict_false(ip6->ip6_hlim != 255)) { + ICMP6STAT_INC(icp6s_invlhlim); nd6log((LOG_ERR, "ICMP6 redirect sent from %s rejected; " "hlim=%d (must be 255)\n", diff --git a/sys/netinet6/nd6_nbr.c b/sys/netinet6/nd6_nbr.c index f96d5a76c4f1..ab55c4dfc697 100644 --- a/sys/netinet6/nd6_nbr.c +++ b/sys/netinet6/nd6_nbr.c @@ -136,7 +136,8 @@ nd6_ns_input(struct mbuf *m, int off, int icmp6len) ifp = m->m_pkthdr.rcvif; ip6 = mtod(m, struct ip6_hdr *); - if (ip6->ip6_hlim != 255) { + if (__predict_false(ip6->ip6_hlim != 255)) { + ICMP6STAT_INC(icp6s_invlhlim); nd6log((LOG_ERR, "nd6_ns_input: invalid hlim (%d) from %s to %s on %s\n", ip6->ip6_hlim, ip6_sprintf(ip6bufs, &ip6->ip6_src), @@ -641,7 +642,8 @@ nd6_na_input(struct mbuf *m, int off, int icmp6len) ifp = m->m_pkthdr.rcvif; ip6 = mtod(m, struct ip6_hdr *); - if (ip6->ip6_hlim != 255) { + if (__predict_false(ip6->ip6_hlim != 255)) { + ICMP6STAT_INC(icp6s_invlhlim); nd6log((LOG_ERR, "nd6_na_input: invalid hlim (%d) from %s to %s on %s\n", ip6->ip6_hlim, ip6_sprintf(ip6bufs, &ip6->ip6_src), diff --git a/sys/netinet6/nd6_rtr.c b/sys/netinet6/nd6_rtr.c index f17ad21e6b6f..1b0e6c2e09cc 100644 --- a/sys/netinet6/nd6_rtr.c +++ b/sys/netinet6/nd6_rtr.c @@ -177,7 +177,8 @@ nd6_rs_input(struct mbuf *m, int off, int icmp6len) /* Sanity checks */ ip6 = mtod(m, struct ip6_hdr *); - if (ip6->ip6_hlim != 255) { + if (__predict_false(ip6->ip6_hlim != 255)) { + ICMP6STAT_INC(icp6s_invlhlim); nd6log((LOG_ERR, "%s: invalid hlim (%d) from %s to %s on %s\n", __func__, ip6->ip6_hlim, ip6_sprintf(ip6bufs, &ip6->ip6_src), @@ -376,7 +377,8 @@ nd6_ra_input(struct mbuf *m, int off, int icmp6len) goto freeit; ip6 = mtod(m, struct ip6_hdr *); - if (ip6->ip6_hlim != 255) { + if (__predict_false(ip6->ip6_hlim != 255)) { + ICMP6STAT_INC(icp6s_invlhlim); nd6log((LOG_ERR, "%s: invalid hlim (%d) from %s to %s on %s\n", __func__, ip6->ip6_hlim, ip6_sprintf(ip6bufs, &ip6->ip6_src), diff --git a/usr.bin/netstat/inet6.c b/usr.bin/netstat/inet6.c index 5ddd7dae79c0..b8d954dbd939 100644 --- a/usr.bin/netstat/inet6.c +++ b/usr.bin/netstat/inet6.c @@ -1063,6 +1063,8 @@ icmp6_stats(u_long off, const char *name, int af1 __unused, int proto __unused) "{N:/neighbour entries overflow%s}\n"); p(icp6s_overflowredirect, "\t{:redirect-overflows/%ju} " "{N:/redirect overflow%s}\n"); + p(icp6s_invlhlim, "\t{:dropped-invalid-hop-limit/%ju} " + "{N:/message%s with invalid hop limit}\n"); xo_close_container("errors"); p(icp6s_pmtuchg, "\t{:path-mtu-changes/%ju} {N:/path MTU change%s}\n"); #undef p