Index | Thread | Search

From:
"Theo de Raadt" <deraadt@openbsd.org>
Subject:
Re: multicast route counter
To:
Alexander Bluhm <bluhm@openbsd.org>
Cc:
tech@openbsd.org
Date:
Wed, 24 Jun 2026 06:12:15 -0600

Download raw body.

Thread
I do not like (relatively very expensive) log messages, so yes.

Alexander Bluhm <bluhm@openbsd.org> 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?
> 
> 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));
>  }
>