From 41b0ee744a9326390b798b064d4e2ce4776e7218 Mon Sep 17 00:00:00 2001 From: Doug Ambrisko Date: Fri, 30 Apr 2004 22:34:12 +0000 Subject: [PATCH] For both ifconfig and route if we didn't get enough memory from the prior sysctl due to the structure growing between calls try again. Also try again for deleting routes if things fail. We've seen route -f fail this way which does not actually flush all routes. This fixes it. It will whine but it will do the work. PR: 56732 Obtained from: IronPort --- sbin/ifconfig/ifconfig.c | 12 ++++++++++-- sbin/route/route.c | 26 ++++++++++++++++++++++---- 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/sbin/ifconfig/ifconfig.c b/sbin/ifconfig/ifconfig.c index 27ffcda4bf2a..b35ed9e9f095 100644 --- a/sbin/ifconfig/ifconfig.c +++ b/sbin/ifconfig/ifconfig.c @@ -417,7 +417,7 @@ main(int argc, char *argv[]) { int c; int all, namesonly, downonly, uponly; - int need_nl = 0; + int need_nl = 0, count = 0; const struct afswtch *afp = 0; int addrcount, ifindex; struct if_msghdr *ifm, *nextifm; @@ -543,6 +543,7 @@ main(int argc, char *argv[]) afp = NULL; /* not a family, NULL */ } +retry: mib[0] = CTL_NET; mib[1] = PF_ROUTE; mib[2] = 0; @@ -558,8 +559,15 @@ main(int argc, char *argv[]) errx(1, "iflist-sysctl-estimate"); if ((buf = malloc(needed)) == NULL) errx(1, "malloc"); - if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) + if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) { + if (errno == ENOMEM && count++ < 10) { + warnx("Routing table grew, retrying"); + free(buf); + sleep(1); + goto retry; + } errx(1, "actual retrieval of interface table"); + } lim = buf + needed; next = buf; diff --git a/sbin/route/route.c b/sbin/route/route.c index deb9d20595e4..10fbee6094c5 100644 --- a/sbin/route/route.c +++ b/sbin/route/route.c @@ -201,7 +201,7 @@ flushroutes(argc, argv) char *argv[]; { size_t needed; - int mib[6], rlen, seqno; + int mib[6], rlen, seqno, count = 0; char *buf, *next, *lim; struct rt_msghdr *rtm; @@ -232,6 +232,7 @@ flushroutes(argc, argv) } else bad: usage(*argv); } +retry: mib[0] = CTL_NET; mib[1] = PF_ROUTE; mib[2] = 0; /* protocol */ @@ -242,8 +243,15 @@ bad: usage(*argv); err(EX_OSERR, "route-sysctl-estimate"); if ((buf = malloc(needed)) == NULL) errx(EX_OSERR, "malloc failed"); - if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) + if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) { + if (errno == ENOMEM && count++ < 10) { + warnx("Routing table grew, retrying"); + sleep(1); + free(buf); + goto retry; + } err(EX_OSERR, "route-sysctl-get"); + } lim = buf + needed; if (verbose) (void) printf("Examining routing table from sysctl\n"); @@ -268,6 +276,8 @@ bad: usage(*argv); if (rlen < (int)rtm->rtm_msglen) { warn("write to routing socket"); (void) printf("got only %d for rlen\n", rlen); + free(buf); + goto retry; break; } seqno++; @@ -1105,9 +1115,10 @@ interfaces() { size_t needed; int mib[6]; - char *buf, *lim, *next; + char *buf, *lim, *next, count = 0; struct rt_msghdr *rtm; +retry2: mib[0] = CTL_NET; mib[1] = PF_ROUTE; mib[2] = 0; /* protocol */ @@ -1118,8 +1129,15 @@ interfaces() err(EX_OSERR, "route-sysctl-estimate"); if ((buf = malloc(needed)) == NULL) errx(EX_OSERR, "malloc failed"); - if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) + if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) { + if (errno == ENOMEM && count++ < 10) { + warnx("Routing table grew, retrying"); + sleep(1); + free(buf); + goto retry2; + } err(EX_OSERR, "actual retrieval of interface table"); + } lim = buf + needed; for (next = buf; next < lim; next += rtm->rtm_msglen) { rtm = (struct rt_msghdr *)next;