From: Claudio Jeker Subject: Re: multicast route counter To: Alexander Bluhm Cc: tech@openbsd.org Date: Wed, 24 Jun 2026 14:11:23 +0200 On Wed, Jun 24, 2026 at 02:06:14PM +0200, Alexander Bluhm wrote: > Hi, > > ip_mforward() contains a static variable that poorly implements a > rate limited log message. Replace the log with a counter. > > While there, also count drops due to time-to-live and hop-limit. > As the default ttl is 1, this is the most common pitfall when > configuring multicast router. A counter helps. > > ok? Sure. OK claudio@ > bluhm > > Index: sys/netinet/ip_mroute.c > =================================================================== > RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/ip_mroute.c,v > diff -u -p -r1.152 ip_mroute.c > --- sys/netinet/ip_mroute.c 23 Jun 2026 19:09:37 -0000 1.152 > +++ sys/netinet/ip_mroute.c 24 Jun 2026 09:42:20 -0000 > @@ -528,6 +528,8 @@ mrt_sysctl_mrtstat(void *oldp, size_t *o > ASSIGN(mrts_q_overflow); > ASSIGN(mrts_pkt2large); > ASSIGN(mrts_upq_sockfull); > + ASSIGN(mrts_time_to_live); > + ASSIGN(mrts_source_route); > > #undef ASSIGN > > @@ -1157,7 +1159,6 @@ ip_mforward(struct mbuf *m, struct ifnet > struct ip *ip = mtod(m, struct ip *); > struct vif *v; > struct rtentry *rt; > - static int srctun = 0; > struct mbuf *mm; > unsigned int rtableid = ifp->if_rdomain; > > @@ -1172,9 +1173,7 @@ ip_mforward(struct mbuf *m, struct ifnet > * Packet arrived through a source-route tunnel. > * Source-route tunnels are no longer supported. > */ > - if ((srctun++ % 1000) == 0) > - log(LOG_ERR, "ip_mforward: received source-routed " > - "packet from %x\n", ntohl(ip->ip_src.s_addr)); > + mrtstat_inc(mrts_source_route); > return (EOPNOTSUPP); > } > > @@ -1182,6 +1181,8 @@ ip_mforward(struct mbuf *m, struct ifnet > * Don't forward a packet with time-to-live of zero or one, > * or a packet destined to a local-only group. > */ > + if (ip->ip_ttl <= 1) > + mrtstat_inc(mrts_time_to_live); > if (ip->ip_ttl <= 1 || IN_LOCAL_GROUP(ip->ip_dst.s_addr)) > return (0); > > Index: sys/netinet/ip_mroute.h > =================================================================== > RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/ip_mroute.h,v > diff -u -p -r1.34 ip_mroute.h > --- sys/netinet/ip_mroute.h 9 May 2025 14:43:47 -0000 1.34 > +++ sys/netinet/ip_mroute.h 24 Jun 2026 09:42:20 -0000 > @@ -165,6 +165,8 @@ struct mrtstat { > u_long mrts_q_overflow; /* pkts dropped - Q overflow */ > u_long mrts_pkt2large; /* pkts dropped - size > BKT SIZE */ > u_long mrts_upq_sockfull; /* upcalls dropped - socket full */ > + u_long mrts_time_to_live; /* ip ttl not above 1 */ > + u_long mrts_source_route; /* packet from source-routed tunnel */ > }; > > #ifdef _KERNEL > @@ -183,6 +185,8 @@ enum mrtstat_counters { > mrts_q_overflow, > mrts_pkt2large, > mrts_upq_sockfull, > + mrts_time_to_live, > + mrts_source_route, > mrts_ncounters > }; > > Index: sys/netinet6/ip6_mroute.c > =================================================================== > RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/ip6_mroute.c,v > diff -u -p -r1.157 ip6_mroute.c > --- sys/netinet6/ip6_mroute.c 23 Jun 2026 18:50:43 -0000 1.157 > +++ sys/netinet6/ip6_mroute.c 24 Jun 2026 09:42:20 -0000 > @@ -474,6 +474,7 @@ mrt6_sysctl_mrt6stat(void *oldp, size_t > ASSIGN(mrt6s_q_overflow); > ASSIGN(mrt6s_pkt2large); > ASSIGN(mrt6s_upq_sockfull); > + ASSIGN(mrt6s_hop_limit); > > #undef ASSIGN > > @@ -938,6 +939,8 @@ ip6_mforward(struct ip6_hdr *ip6, struct > * Don't forward a packet with Hop limit of zero or one, > * or a packet destined to a local-only group. > */ > + if (ip6->ip6_hlim <= 1) > + mrt6stat_inc(mrt6s_hop_limit); > if (ip6->ip6_hlim <= 1 || IN6_IS_ADDR_MC_INTFACELOCAL(&ip6->ip6_dst) || > IN6_IS_ADDR_MC_LINKLOCAL(&ip6->ip6_dst)) > return 0; > Index: sys/netinet6/ip6_mroute.h > =================================================================== > RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/ip6_mroute.h,v > diff -u -p -r1.25 ip6_mroute.h > --- sys/netinet6/ip6_mroute.h 19 May 2025 04:54:04 -0000 1.25 > +++ sys/netinet6/ip6_mroute.h 24 Jun 2026 09:42:20 -0000 > @@ -146,6 +146,7 @@ struct mrt6stat { > u_int64_t mrt6s_q_overflow; /* pkts dropped - Q overflow */ > u_int64_t mrt6s_pkt2large; /* pkts dropped - size > BKT SIZE */ > u_int64_t mrt6s_upq_sockfull; /* upcalls dropped - socket full */ > + u_int64_t mrt6s_hop_limit; /* ip6 hlim not above one */ > }; > > /* > @@ -206,6 +207,7 @@ enum mrt6stat_counters { > mrt6s_q_overflow, > mrt6s_pkt2large, > mrt6s_upq_sockfull, > + mrt6s_hop_limit, > mrt6s_ncounters > }; > > Index: usr.bin/netstat/mroute.c > =================================================================== > RCS file: /data/mirror/openbsd/cvs/src/usr.bin/netstat/mroute.c,v > diff -u -p -r1.29 mroute.c > --- usr.bin/netstat/mroute.c 6 Jun 2025 20:37:06 -0000 1.29 > +++ usr.bin/netstat/mroute.c 24 Jun 2026 09:43:28 -0000 > @@ -188,4 +188,8 @@ mrt_stats(void) > mrtstat.mrts_pkt2large, plural(mrtstat.mrts_pkt2large)); > printf("\t%lu datagram%s dropped due to full socket buffer\n", > mrtstat.mrts_upq_sockfull, plural(mrtstat.mrts_upq_sockfull)); > + printf("\t%lu datagram%s exceeded time-to-live not forwarded\n", > + mrtstat.mrts_time_to_live, plural(mrtstat.mrts_time_to_live)); > + printf("\t%lu datagram%s dropped due to source-routing\n", > + mrtstat.mrts_source_route, plural(mrtstat.mrts_source_route)); > } > Index: usr.bin/netstat/mroute6.c > =================================================================== > RCS file: /data/mirror/openbsd/cvs/src/usr.bin/netstat/mroute6.c,v > diff -u -p -r1.27 mroute6.c > --- usr.bin/netstat/mroute6.c 6 Jun 2025 20:37:06 -0000 1.27 > +++ usr.bin/netstat/mroute6.c 24 Jun 2026 09:41:30 -0000 > @@ -221,4 +221,6 @@ mrt6_stats(void) > mrt6stat.mrt6s_pkt2large, plural(mrt6stat.mrt6s_pkt2large)); > printf("\t%llu datagram%s dropped due to full socket buffer\n", > mrt6stat.mrt6s_upq_sockfull, plural(mrt6stat.mrt6s_upq_sockfull)); > + printf("\t%llu datagram%s exceeded hop-limit not forwarded\n", > + mrt6stat.mrt6s_hop_limit, plural(mrt6stat.mrt6s_hop_limit)); > } > -- :wq Claudio