From owner-freebsd-current@FreeBSD.ORG Fri Feb 21 09:22:18 2014 Return-Path: Delivered-To: current@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id D8C0CA91 for ; Fri, 21 Feb 2014 09:22:18 +0000 (UTC) Received: from mail.allbsd.org (gatekeeper.allbsd.org [IPv6:2001:2f0:104:e001::32]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id 2E5B01564 for ; Fri, 21 Feb 2014 09:22:18 +0000 (UTC) Received: from alph.d.allbsd.org (p2106-ipbf2009funabasi.chiba.ocn.ne.jp [114.146.169.106]) (authenticated bits=128) by mail.allbsd.org (8.14.5/8.14.5) with ESMTP id s1L9LsVM077268 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Fri, 21 Feb 2014 18:22:04 +0900 (JST) (envelope-from hrs@FreeBSD.org) Received: from localhost (localhost [IPv6:::1]) (authenticated bits=0) by alph.d.allbsd.org (8.14.7/8.14.7) with ESMTP id s1L9Lq8p033868; Fri, 21 Feb 2014 18:21:54 +0900 (JST) (envelope-from hrs@FreeBSD.org) Date: Fri, 21 Feb 2014 18:20:37 +0900 (JST) Message-Id: <20140221.182037.200669298555875226.hrs@allbsd.org> To: ianf@clue.co.za Subject: Re: netstat: sysctl: net.route.0.0.dump.0: Cannot allocate memory From: Hiroki Sato In-Reply-To: References: <20140221.172017.821481836359198829.hrs@allbsd.org> X-PGPkey-fingerprint: BDB3 443F A5DD B3D0 A530 FFD7 4F2C D3D8 2793 CF2D X-Mailer: Mew version 6.5 on Emacs 24.3 / Mule 6.0 (HANACHIRUSATO) Mime-Version: 1.0 Content-Type: Multipart/Signed; protocol="application/pgp-signature"; micalg=pgp-sha1; boundary="--Security_Multipart0(Fri_Feb_21_18_20_37_2014_800)--" Content-Transfer-Encoding: 7bit X-Virus-Scanned: clamav-milter 0.97.4 at gatekeeper.allbsd.org X-Virus-Status: Clean X-Greylist: Sender DNS name whitelisted, not delayed by milter-greylist-4.2.7 (mail.allbsd.org [133.31.130.32]); Fri, 21 Feb 2014 18:22:05 +0900 (JST) X-Spam-Status: No, score=-93.8 required=13.0 tests=CONTENT_TYPE_PRESENT, FAKEDWORD_VERTICALLINE,RCVD_IN_PBL,RCVD_IN_RP_RNBL,SPF_SOFTFAIL, USER_IN_WHITELIST autolearn=no version=3.3.2 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on gatekeeper.allbsd.org Cc: current@FreeBSD.org X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.17 Precedence: list List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 21 Feb 2014 09:22:18 -0000 ----Security_Multipart0(Fri_Feb_21_18_20_37_2014_800)-- Content-Type: Multipart/Mixed; boundary="--Next_Part(Fri_Feb_21_18_20_37_2014_329)--" Content-Transfer-Encoding: 7bit ----Next_Part(Fri_Feb_21_18_20_37_2014_329)-- Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit Ian FREISLICH wrote in : ia> Hiroki Sato wrote: ia> > ia> While recieving my routing table I used to be able to check how far ia> > ia> it got by counting the output netstat -rn. It takes about 2 seconds ia> > ia> to recieve the routes from my route-server, but over a minute to ia> > ia> update the kernel routing table. ia> > ia> ia> > ia> I'm now getting this error until zebra completes route insertion. ia> > ia> ia> > ia> [firewall1.jnb1] ~ $ netstat -rn |wc -l ia> > ia> netstat: sysctl: net.route.0.0.dump.0: Cannot allocate memory ia> > ia> 1 ia> > ia> [firewall1.jnb1] ~ $ netstat -rn |wc -l ia> > ia> 480446 ia> > ia> > Perhaps does the attached patch fix this? ia> ia> Sadly, not. Hm, how about the attached one? I think the cause is just a race when length of the sysctl's output is changed in kernel after the buffer allocation in userspace, not memory shortage. Size of the routing table can quickly change. -- Hiroki ----Next_Part(Fri_Feb_21_18_20_37_2014_329)-- Content-Type: Text/X-Patch; charset=us-ascii Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="netstat-1.diff" Index: usr.bin/netstat/route.c =================================================================== --- usr.bin/netstat/route.c (revision 262283) +++ usr.bin/netstat/route.c (working copy) @@ -69,6 +69,7 @@ #include #include #include +#include #include "netstat.h" #define kget(p, d) (kread((u_long)(p), (char *)&(d), sizeof (d))) @@ -560,7 +561,7 @@ char *buf, *next, *lim; struct rt_msghdr *rtm; struct sockaddr *sa; - int fam = 0, ifindex = 0, size; + int fam = 0, ifindex = 0, size, count = 0; struct ifaddrs *ifap, *ifa; struct sockaddr_dl *sdl; @@ -600,6 +601,7 @@ freeifaddrs(ifap); +retry: mib[0] = CTL_NET; mib[1] = PF_ROUTE; mib[2] = 0; @@ -607,19 +609,24 @@ mib[4] = NET_RT_DUMP; mib[5] = 0; mib[6] = fibnum; - if (sysctl(mib, 7, NULL, &needed, NULL, 0) < 0) { + if (sysctl(mib, nitems(mib), NULL, &needed, NULL, 0) < 0) err(1, "sysctl: net.route.0.%d.dump.%d estimate", af, fibnum); + if ((buf = malloc(needed)) == NULL) + errx(2, "malloc(%zd)", needed); + if (sysctl(mib, nitems(mib), buf, &needed, NULL, 0) < 0) { + if (errno == ENOMEM && count++ < 20) { + warnx("Routing table grew, retrying"); + sleep(1); + free(buf); + goto retry; + } else + err(1, "sysctl: net.route.0.%d.dump.%d", af, fibnum); } - - if ((buf = malloc(needed)) == 0) { - errx(2, "malloc(%lu)", (unsigned long)needed); - } - if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) { - err(1, "sysctl: net.route.0.%d.dump.%d", af, fibnum); - } lim = buf + needed; for (next = buf; next < lim; next += rtm->rtm_msglen) { rtm = (struct rt_msghdr *)next; + if (rtm->rtm_version != RTM_VERSION) + continue; /* * Peek inside header to determine AF */ ----Next_Part(Fri_Feb_21_18_20_37_2014_329)---- ----Security_Multipart0(Fri_Feb_21_18_20_37_2014_800)-- Content-Type: application/pgp-signature Content-Transfer-Encoding: 7bit -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iEYEABECAAYFAlMHGmUACgkQTyzT2CeTzy1+ZQCcDA3RXqqLhsnrSAfBkB0joLyy r70AnAjWvIMo0M9RJkKR9sprugWyW44j =UO1z -----END PGP SIGNATURE----- ----Security_Multipart0(Fri_Feb_21_18_20_37_2014_800)----