git: 3eaffc626589 - main - netinet6: allow disabling excess log messages

From: Pawel Biernacki <kaktus_at_FreeBSD.org>
Date: Mon, 13 Mar 2023 16:49:23 UTC
The branch main has been updated by kaktus:

URL: https://cgit.FreeBSD.org/src/commit/?id=3eaffc626589eb2fc20a3c9c87eb8ab0ee89e783

commit 3eaffc626589eb2fc20a3c9c87eb8ab0ee89e783
Author:     Pawel Biernacki <kaktus@FreeBSD.org>
AuthorDate: 2023-03-13 16:36:11 +0000
Commit:     Pawel Biernacki <kaktus@FreeBSD.org>
CommitDate: 2023-03-13 16:46:21 +0000

    netinet6: allow disabling excess log messages
    
    RFC 4443 specifies cases where certain packets, like those originating from
    local-scope addresses destined outside of the scope shouldn't be forwarded.
    The current practice is to drop them, send ICMPv6 message where appropriate,
    and log the message:
    
    cannot forward src fe80:10::426:82ff:fe36:1d8, dst 2001:db8:db8::10, nxt
    58, rcvif vlan5, outif vlan2
    
    At times the volume of such messages cat get very high. Let's allow local
    admins to disable such messages on per vnet basis, keeping the current
    default (log).
    
    Reported by:    zarychtam@plan-b.pwste.edu.pl
    Reviewed by:    zlei (previous version), pauamma (docs)
    Differential Revision:  https://reviews.freebsd.org/D38644
---
 share/man/man4/inet6.4     | 20 ++++++++++++++++++--
 sys/netinet6/in6_proto.c   |  5 +++++
 sys/netinet6/ip6_forward.c |  6 ++++--
 sys/netinet6/ip6_mroute.c  |  3 ++-
 sys/netinet6/ip6_var.h     |  3 +++
 5 files changed, 32 insertions(+), 5 deletions(-)

diff --git a/share/man/man4/inet6.4 b/share/man/man4/inet6.4
index 87c57ea2c3d2..3a950e746266 100644
--- a/share/man/man4/inet6.4
+++ b/share/man/man4/inet6.4
@@ -29,7 +29,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd November 12, 2021
+.Dd February 22, 2023
 .Dt INET6 4
 .Os
 .Sh NAME
@@ -185,7 +185,9 @@ The
 .Tn ICMPv6
 message protocol is accessible from a raw socket.
 .Ss MIB Variables
-A number of variables are implemented in the net.inet6 branch of the
+A number of variables are implemented in the
+.Va net.inet6
+branch of the
 .Xr sysctl 3
 MIB.
 In addition to the variables supported by the transport protocols
@@ -341,6 +343,11 @@ mapped address on
 .Dv AF_INET6
 sockets.
 Defaults to on.
+.It Va ip6.log_cannot_forward
+Boolean: log packets that can't be forwarded because of unspecified source
+address or destination address beyond the scope of the source address as
+described in RFC4443.
+Enabled by default.
 .It Va ip6.source_address_validation
 Boolean: perform source address validation for packets destined for the local
 host.
@@ -440,6 +447,15 @@ sockets.
 .Xr ip6 4 ,
 .Xr tcp 4 ,
 .Xr udp 4
+.Rs
+.%A A. Conta
+.%A S. Deering
+.%A M. Gupta
+.%T "Internet Control Message Protocol (ICMPv6) for the Internet" \
+    "Protocol Version 6 (IPv6) Specification"
+.%R RFC 4443
+.%D March 2006
+.Re
 .Sh STANDARDS
 .Rs
 .%A Tatsuya Jinmei
diff --git a/sys/netinet6/in6_proto.c b/sys/netinet6/in6_proto.c
index ca1257456326..1f2a41dd51de 100644
--- a/sys/netinet6/in6_proto.c
+++ b/sys/netinet6/in6_proto.c
@@ -179,6 +179,7 @@ VNET_DEFINE(int, ip6stealth) = 0;
 #endif
 VNET_DEFINE(int, nd6_onlink_ns_rfc4861) = 0;/* allow 'on-link' nd6 NS
 					     * (RFC 4861) */
+VNET_DEFINE(bool, ip6_log_cannot_forward) = 1;
 
 /* icmp6 */
 /*
@@ -342,6 +343,10 @@ SYSCTL_INT(_net_inet6_ip6, IPV6CTL_STEALTH, stealth, CTLFLAG_VNET | CTLFLAG_RW,
 	&VNET_NAME(ip6stealth), 0,
 	"Forward IPv6 packets without decrementing their TTL");
 #endif
+SYSCTL_BOOL(_net_inet6_ip6, OID_AUTO,
+	log_cannot_forward, CTLFLAG_VNET | CTLFLAG_RW,
+	&VNET_NAME(ip6_log_cannot_forward), 1,
+	"Log packets that cannot be forwarded");
 
 /* net.inet6.icmp6 */
 SYSCTL_INT(_net_inet6_icmp6, ICMPV6CTL_REDIRACCEPT, rediraccept,
diff --git a/sys/netinet6/ip6_forward.c b/sys/netinet6/ip6_forward.c
index a95e58ba09a1..fc00eab4b784 100644
--- a/sys/netinet6/ip6_forward.c
+++ b/sys/netinet6/ip6_forward.c
@@ -114,7 +114,8 @@ ip6_forward(struct mbuf *m, int srcrt)
 	    IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_src)) {
 		IP6STAT_INC(ip6s_cantforward);
 		/* XXX in6_ifstat_inc(rt->rt_ifp, ifs6_in_discard) */
-		if (V_ip6_log_time + V_ip6_log_interval < time_uptime) {
+		if (V_ip6_log_cannot_forward &&
+		    (V_ip6_log_time + V_ip6_log_interval < time_uptime)) {
 			V_ip6_log_time = time_uptime;
 			log(LOG_DEBUG,
 			    "cannot forward "
@@ -221,7 +222,8 @@ again:
 		IP6STAT_INC(ip6s_badscope);
 		in6_ifstat_inc(nh->nh_ifp, ifs6_in_discard);
 
-		if (V_ip6_log_time + V_ip6_log_interval < time_uptime) {
+		if (V_ip6_log_cannot_forward &&
+		    (V_ip6_log_time + V_ip6_log_interval < time_uptime)) {
 			V_ip6_log_time = time_uptime;
 			log(LOG_DEBUG,
 			    "cannot forward "
diff --git a/sys/netinet6/ip6_mroute.c b/sys/netinet6/ip6_mroute.c
index e690cb64894f..cdccd04abc63 100644
--- a/sys/netinet6/ip6_mroute.c
+++ b/sys/netinet6/ip6_mroute.c
@@ -1099,7 +1099,8 @@ X_ip6_mforward(struct ip6_hdr *ip6, struct ifnet *ifp, struct mbuf *m)
 	 */
 	if (IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_src)) {
 		IP6STAT_INC(ip6s_cantforward);
-		if (V_ip6_log_time + V_ip6_log_interval < time_uptime) {
+		if (V_ip6_log_cannot_forward &&
+		    (V_ip6_log_time + V_ip6_log_interval < time_uptime)) {
 			V_ip6_log_time = time_uptime;
 			log(LOG_DEBUG,
 			    "cannot forward "
diff --git a/sys/netinet6/ip6_var.h b/sys/netinet6/ip6_var.h
index 32158534ef5b..469b49459e2c 100644
--- a/sys/netinet6/ip6_var.h
+++ b/sys/netinet6/ip6_var.h
@@ -339,6 +339,9 @@ VNET_DECLARE(int, nd6_ignore_ipv6_only_ra);
 #define	V_nd6_ignore_ipv6_only_ra	VNET(nd6_ignore_ipv6_only_ra)
 #endif
 
+VNET_DECLARE(bool, ip6_log_cannot_forward);
+#define	V_ip6_log_cannot_forward	VNET(ip6_log_cannot_forward)
+
 extern struct	pr_usrreqs rip6_usrreqs;
 struct sockopt;