From owner-svn-src-head@freebsd.org Sat Mar 7 08:41:11 2020 Return-Path: Delivered-To: svn-src-head@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id AC79C25F044; Sat, 7 Mar 2020 08:41:11 +0000 (UTC) (envelope-from hrs@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 48ZHyH2ZyYz3LK0; Sat, 7 Mar 2020 08:41:11 +0000 (UTC) (envelope-from hrs@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 25DE0651D; Sat, 7 Mar 2020 08:41:11 +0000 (UTC) (envelope-from hrs@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 0278fBRp077262; Sat, 7 Mar 2020 08:41:11 GMT (envelope-from hrs@FreeBSD.org) Received: (from hrs@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 0278fAUl077260; Sat, 7 Mar 2020 08:41:10 GMT (envelope-from hrs@FreeBSD.org) Message-Id: <202003070841.0278fAUl077260@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: hrs set sender to hrs@FreeBSD.org using -f From: Hiroki Sato Date: Sat, 7 Mar 2020 08:41:10 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r358730 - in head: sys/netinet usr.bin/netstat X-SVN-Group: head X-SVN-Commit-Author: hrs X-SVN-Commit-Paths: in head: sys/netinet usr.bin/netstat X-SVN-Commit-Revision: 358730 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 07 Mar 2020 08:41:11 -0000 Author: hrs Date: Sat Mar 7 08:41:10 2020 New Revision: 358730 URL: https://svnweb.freebsd.org/changeset/base/358730 Log: Fix an issue of net.inet.igmp.stats handler. The header of (struct igmpstat) could be cleared by sysctl(3). This can be reproduced by "netstat -s -z -p igmp". PR: 244584 MFC after: 1 week Modified: head/sys/netinet/igmp.c head/usr.bin/netstat/inet.c Modified: head/sys/netinet/igmp.c ============================================================================== --- head/sys/netinet/igmp.c Sat Mar 7 03:58:58 2020 (r358729) +++ head/sys/netinet/igmp.c Sat Mar 7 08:41:10 2020 (r358730) @@ -145,6 +145,7 @@ static void igmp_v3_suppress_group_record(struct in_mu static int sysctl_igmp_default_version(SYSCTL_HANDLER_ARGS); static int sysctl_igmp_gsr(SYSCTL_HANDLER_ARGS); static int sysctl_igmp_ifinfo(SYSCTL_HANDLER_ARGS); +static int sysctl_igmp_stat(SYSCTL_HANDLER_ARGS); static const struct netisr_handler igmp_nh = { .nh_name = "igmp", @@ -260,8 +261,9 @@ VNET_DEFINE_STATIC(int, igmp_default_version) = IGMP_V /* * Virtualized sysctls. */ -SYSCTL_STRUCT(_net_inet_igmp, IGMPCTL_STATS, stats, CTLFLAG_VNET | CTLFLAG_RW, - &VNET_NAME(igmpstat), igmpstat, ""); +SYSCTL_PROC(_net_inet_igmp, IGMPCTL_STATS, stats, + CTLFLAG_VNET | CTLTYPE_STRUCT | CTLFLAG_RW | CTLFLAG_MPSAFE, + &VNET_NAME(igmpstat), 0, sysctl_igmp_stat, "S,igmpstat", ""); SYSCTL_INT(_net_inet_igmp, OID_AUTO, recvifkludge, CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(igmp_recvifkludge), 0, "Rewrite IGMPv1/v2 reports from 0.0.0.0 to contain subnet address"); @@ -333,6 +335,59 @@ igmp_restore_context(struct mbuf *m) #endif #endif return (m->m_pkthdr.flowid); +} + +/* + * IGMP statistics. + */ +static int +sysctl_igmp_stat(SYSCTL_HANDLER_ARGS) +{ + struct igmpstat igps0; + int error; + char *p; + + error = sysctl_wire_old_buffer(req, sizeof(V_igmpstat)); + if (error) + return (error); + + if (req->oldptr != NULL) { + if (req->oldlen < sizeof(V_igmpstat)) + error = ENOMEM; + else + error = SYSCTL_OUT(req, &V_igmpstat, + sizeof(V_igmpstat)); + } else + req->validlen = sizeof(V_igmpstat); + if (error) + goto out; + if (req->newptr != NULL) { + if (req->newlen < sizeof(V_igmpstat)) + error = ENOMEM; + else + error = SYSCTL_IN(req, &igps0, + sizeof(igps0)); + if (error) + goto out; + /* + * igps0 must be "all zero". + */ + p = (char *)&igps0; + while (*p == '\0' && p < (char *)&igps0 + sizeof(igps0)) + p++; + if (p != (char *)&igps0 + sizeof(igps0)) { + error = EINVAL; + goto out; + } + /* + * Avoid overwrite of the version and length field. + */ + igps0.igps_version = V_igmpstat.igps_version; + igps0.igps_len = V_igmpstat.igps_len; + bcopy(&igps0, &V_igmpstat, sizeof(V_igmpstat)); + } +out: + return (error); } /* Modified: head/usr.bin/netstat/inet.c ============================================================================== --- head/usr.bin/netstat/inet.c Sat Mar 7 03:58:58 2020 (r358729) +++ head/usr.bin/netstat/inet.c Sat Mar 7 08:41:10 2020 (r358730) @@ -1222,10 +1222,26 @@ void igmp_stats(u_long off, const char *name, int af1 __unused, int proto __unused) { struct igmpstat igmpstat; + int error, zflag0; if (fetch_stats("net.inet.igmp.stats", 0, &igmpstat, sizeof(igmpstat), kread) != 0) return; + /* + * Reread net.inet.igmp.stats when zflag == 1. + * This is because this MIB contains version number and + * length of the structure which are not set when clearing + * the counters. + */ + zflag0 = zflag; + if (zflag) { + zflag = 0; + error = fetch_stats("net.inet.igmp.stats", 0, &igmpstat, + sizeof(igmpstat), kread); + zflag = zflag0; + if (error) + return; + } if (igmpstat.igps_version != IGPS_VERSION_3) { xo_warnx("%s: version mismatch (%d != %d)", __func__,