Index | Thread | Search

From:
Jan Klemkow <jan@openbsd.org>
Subject:
Re: netstat: fix output of mroute6 stats
To:
Alexander Bluhm <bluhm@openbsd.org>
Cc:
tech@openbsd.org
Date:
Mon, 19 May 2025 14:37:27 +0200

Download raw body.

Thread
On Mon, May 19, 2025 at 04:36:46PM +0900, Alexander Bluhm wrote:
> On Mon, May 19, 2025 at 01:55:25AM +0200, Jan Klemkow wrote:
> > 
> > Wrong mrt6proto check prevents netstat from printing the mroute6 stats.
> > Using the same mrt6proto check here as in mroute6pr() above in this
> > file.
> > 
> > ok?

ok jan@

> I compared our logic with NetBSD to understand why we ended here.
> 
> mrt6proto is alway 0 since PIM has been removed.  Before it always
> returned IPPROTO_PIM.
> 
> This sysctl is rather useless except to detect missing MROUTING
> support in the kernel.  When we used kvm_read() it was reasonable
> to check that the mrt6proto value was not 0.  But nowadays already
> the sysctl fails.  The code is never reached.
> 
> Which leads to the next bug.  While netstat checks for ENOPROTOOPT,
> the kernel does
> #ifdef MROUTING
> 	...
> #else
>         case IPV6CTL_MRTSTATS:
>         case IPV6CTL_MRTPROTO:
>         case IPV6CTL_MRTMIF:
>         case IPV6CTL_MRTMFC:
>                 return (EOPNOTSUPP);
> #endif
> 
> We may delete sysctl IPCTL_MRTPROTO in kernel later.  Not sure
> whether it makes sense to keep it in case we reinroduce PIM support.
> 
> Remove dead code.  Fix error code.  Move error message to make it
> work.  Remove useless IPCTL_MRTPROTO before IPCTL_MRTSTATS.
> 
> before:
> root@v74:.../~# netstat -g
> netstat: mroute: Operation not supported
> netstat: mroute: Operation not supported
> 
> after:
> root@v74:.../~# /home/bluhm/netstat -g
> no multicast routing compiled into this system
> no IPv6 multicast routing compiled into this system
> 
> ok?
> 
> bluhm
> 
> Index: mroute.c
> ===================================================================
> RCS file: /data/mirror/openbsd/cvs/src/usr.bin/netstat/mroute.c,v
> diff -u -p -r1.27 mroute.c
> --- mroute.c	9 May 2025 14:46:36 -0000	1.27
> +++ mroute.c	19 May 2025 07:29:43 -0000
> @@ -74,19 +74,10 @@ mroutepr(void)
>  
>  	if (sysctl(mib, sizeof(mib) / sizeof(mib[0]),
>  	    &mrtproto, &len, NULL, 0) == -1) {
> -		if (errno != ENOPROTOOPT)
> +		if (errno != EOPNOTSUPP)
>  			warn("mroute");
> -		return;
> -	}
> -	switch (mrtproto) {
> -	case 0:
>  		printf("no multicast routing compiled into this system\n");
>  		return;
> -	case IGMP_DVMRP:
> -		break;
> -	default:
> -		printf("multicast routing protocol %u, unknown\n", mrtproto);
> -		return;
>  	}
>  
>  	saved_nflag = nflag;
> @@ -158,36 +149,15 @@ mroutepr(void)
>  void
>  mrt_stats(void)
>  {
> -	u_int mrtproto;
>  	struct mrtstat mrtstat;
> -	int mib[] = { CTL_NET, PF_INET, IPPROTO_IP, IPCTL_MRTPROTO };
> -	int mib2[] = { CTL_NET, PF_INET, IPPROTO_IP, IPCTL_MRTSTATS };
> -	size_t len = sizeof(int);
> +	int mib[] = { CTL_NET, PF_INET, IPPROTO_IP, IPCTL_MRTSTATS };
> +	size_t len = sizeof(mrtstat);
>  
>  	if (sysctl(mib, sizeof(mib) / sizeof(mib[0]),
> -	    &mrtproto, &len, NULL, 0) == -1) {
> -		if (errno != ENOPROTOOPT)
> -			warn("mroute");
> -		return;
> -	}
> -	switch (mrtproto) {
> -	case 0:
> -		printf("no multicast routing compiled into this system\n");
> -		return;
> -
> -	case IGMP_DVMRP:
> -		break;
> -
> -	default:
> -		printf("multicast routing protocol %u, unknown\n", mrtproto);
> -		return;
> -	}
> -
> -	len = sizeof(mrtstat);
> -	if (sysctl(mib2, sizeof(mib2) / sizeof(mib2[0]),
>  	    &mrtstat, &len, NULL, 0) == -1) {
> -		if (errno != ENOPROTOOPT)
> +		if (errno != EOPNOTSUPP)
>  			warn("mroute");
> +		printf("no multicast routing compiled into this system\n");
>  		return;
>  	}
>  
> Index: mroute6.c
> ===================================================================
> RCS file: /data/mirror/openbsd/cvs/src/usr.bin/netstat/mroute6.c,v
> diff -u -p -r1.25 mroute6.c
> --- mroute6.c	5 Dec 2021 22:36:19 -0000	1.25
> +++ mroute6.c	19 May 2025 07:29:43 -0000
> @@ -97,16 +97,9 @@ mroute6pr(void)
>  
>  	if (sysctl(mib, sizeof(mib) / sizeof(mib[0]),
>  	    &mrtproto, &len, NULL, 0) == -1) {
> -		if (errno != ENOPROTOOPT)
> +		if (errno != EOPNOTSUPP)
>  			warn("mroute");
> -		return;
> -	}
> -	switch (mrtproto) {
> -	case 0:
> -		break;
> -	default:
> -		printf("IPv6 multicast routing protocol %u, unknown\n",
> -		    mrtproto);
> +		printf("no IPv6 multicast routing compiled into this system\n");
>  		return;
>  	}
>  
> @@ -190,32 +183,14 @@ void
>  mrt6_stats(void)
>  {
>  	struct mrt6stat mrt6stat;
> -	u_int mrt6proto;
> -	int mib[] = { CTL_NET, PF_INET6, IPPROTO_IPV6, IPV6CTL_MRTPROTO };
> -	int mib2[] = { CTL_NET, PF_INET6, IPPROTO_IPV6, IPV6CTL_MRTSTATS };
> -	size_t len = sizeof(int);
> +	int mib[] = { CTL_NET, PF_INET6, IPPROTO_IPV6, IPV6CTL_MRTSTATS };
> +	size_t len = sizeof(mrt6stat);
>  
>  	if (sysctl(mib, sizeof(mib) / sizeof(mib[0]),
> -	    &mrt6proto, &len, NULL, 0) == -1) {
> -		if (errno != ENOPROTOOPT)
> -			warn("mroute");
> -		return;
> -	}
> -	switch (mrt6proto) {
> -	case 0:
> -		printf("no IPv6 multicast routing compiled into this system\n");
> -		return;
> -	default:
> -		printf("IPv6 multicast routing protocol %u, unknown\n",
> -		    mrt6proto);
> -		return;
> -	}
> -
> -	len = sizeof(mrt6stat);
> -	if (sysctl(mib2, sizeof(mib2) / sizeof(mib2[0]),
>  	    &mrt6stat, &len, NULL, 0) == -1) {
> -		if (errno != ENOPROTOOPT)
> -			warn("mroute");
> +		if (errno != EOPNOTSUPP)
> +			warn("mroute6");
> +		printf("no IPv6 multicast routing compiled into this system\n");
>  		return;
>  	}
>  
>