From: Jan Klemkow Subject: Re: netstat: fix output of mroute6 stats To: Alexander Bluhm Cc: tech@openbsd.org Date: Mon, 19 May 2025 14:37:27 +0200 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; > } > >