From: Alexander Bluhm Subject: Re: netstat: fix output of mroute6 stats To: Jan Klemkow Cc: tech@openbsd.org Date: Mon, 19 May 2025 16:36:46 +0900 On Mon, May 19, 2025 at 01:55:25AM +0200, Jan Klemkow wrote: > Hi, > > Wrong mrt6proto check prevents netstat from printing the mroute6 stats. > Using the same mrt6proto check here as in mroute6pr() above in this > file. > > ok? 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; }