Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 24 Feb 2014 13:09:24 +0900 (JST)
From:      Hiroki Sato <hrs@FreeBSD.org>
To:        ianf@clue.co.za
Cc:        current@FreeBSD.org
Subject:   Re: netstat: sysctl: net.route.0.0.dump.0: Cannot allocate memory
Message-ID:  <20140224.130924.1512809959333112659.hrs@allbsd.org>
In-Reply-To: <E1WGmTE-0000nr-Us@clue.co.za>
References:  <E1WGkzK-0000gb-E2@clue.co.za> <E1WGltZ-0000kf-1A@clue.co.za> <E1WGmTE-0000nr-Us@clue.co.za>

next in thread | previous in thread | raw e-mail | index | archive | help
----Security_Multipart0(Mon_Feb_24_13_09_24_2014_476)--
Content-Type: Multipart/Mixed;
 boundary="--Next_Part(Mon_Feb_24_13_09_24_2014_200)--"
Content-Transfer-Encoding: 7bit

----Next_Part(Mon_Feb_24_13_09_24_2014_200)--
Content-Type: Text/Plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Ian FREISLICH <ianf@clue.co.za> wrote
  in <E1WGmTE-0000nr-Us@clue.co.za>:

ia> Hiroki Sato wrote:
ia> >  Hm, how about the attached one?
ia> >
ia> >  I think the cause is just a race when length of the sysctl's output
ia> >  is changed in kernel after the buffer allocation in userspace, not
ia> >  memory shortage.  Size of the routing table can quickly change.
ia>
ia> You are correct.  It's growing at about 9000 entries per second (I
ia> wish it were faster).
ia>
ia> This is what the output looks like now.  I guess I'm not the average
ia> case.

 Can you try the attached patch?  It will attempt to enlarge the
 buffer every retry.

-- Hiroki

----Next_Part(Mon_Feb_24_13_09_24_2014_200)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="netstat-2.diff"

Index: route.c
===================================================================
--- route.c	(revision 262313)
+++ route.c	(working copy)
@@ -69,6 +69,7 @@
 #include <sysexits.h>
 #include <unistd.h>
 #include <err.h>
+#include <errno.h>
 #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,27 @@
 	mib[4] = NET_RT_DUMP;
 	mib[5] = 0;
 	mib[6] = fibnum;
-	if (sysctl(mib, 7, NULL, &needed, NULL, 0) < 0) {
-		err(1, "sysctl: net.route.0.%d.dump.%d estimate", af, fibnum);
+	if (sysctl(mib, nitems(mib), NULL, &needed, NULL, 0) < 0)
+		err(EX_OSERR, "sysctl: net.route.0.%d.dump.%d estimate", af,
+		    fibnum);
+	needed += PAGE_SIZE * (count + 1);
+	if ((buf = malloc(needed)) == NULL)
+		errx(EX_OSERR, "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(EX_OSERR, "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
 		 */
@@ -632,6 +642,7 @@
 		}
 		p_rtentry_sysctl(rtm);
 	}
+	free(buf);
 }

 static void

----Next_Part(Mon_Feb_24_13_09_24_2014_200)----

----Security_Multipart0(Mon_Feb_24_13_09_24_2014_476)--
Content-Type: application/pgp-signature
Content-Transfer-Encoding: 7bit

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1

iEYEABECAAYFAlMKxfQACgkQTyzT2CeTzy311gCcCe7gnRiQIX0bqSKt4ykC6hX/
EiIAoK2IhblmxU68fA+6Xbw/YiJ5w8U9
=+fo0
-----END PGP SIGNATURE-----

----Security_Multipart0(Mon_Feb_24_13_09_24_2014_476)----



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20140224.130924.1512809959333112659.hrs>