aboutsummaryrefslogtreecommitdiff
path: root/usr.bin/netstat/route.c
diff options
context:
space:
mode:
authorAlexander V. Chernikov <melifaro@FreeBSD.org>2013-12-20 00:17:26 +0000
committerAlexander V. Chernikov <melifaro@FreeBSD.org>2013-12-20 00:17:26 +0000
commitfc47e028bb31ecd84ced50a31b6f0981bfd7c45d (patch)
tree15128778b84a316461bc6ac0321ccfd38190f556 /usr.bin/netstat/route.c
parent851d84f1b536fa6a9ac4f028dd4445d822ae875b (diff)
downloadsrc-fc47e028bb31ecd84ced50a31b6f0981bfd7c45d.tar.gz
src-fc47e028bb31ecd84ced50a31b6f0981bfd7c45d.zip
Use more fine-grained kvm(3) symbol lookup: routing code retrieves only
necessary symbols needed per subsystem. Main kvm(3) init is now delayed as much as possbile. This finally fixes performance issues reported in kern/167204. Some non-working code (ng_socket.ko symbol addresses calculation) removed. Some global variables eliminated. PR: kern/167204 MFC after: 4 weeks
Notes
Notes: svn path=/head/; revision=259638
Diffstat (limited to 'usr.bin/netstat/route.c')
-rw-r--r--usr.bin/netstat/route.c44
1 files changed, 32 insertions, 12 deletions
diff --git a/usr.bin/netstat/route.c b/usr.bin/netstat/route.c
index 31ef3c0e3217..a5d2635bfb67 100644
--- a/usr.bin/netstat/route.c
+++ b/usr.bin/netstat/route.c
@@ -61,6 +61,7 @@ __FBSDID("$FreeBSD$");
#include <ifaddrs.h>
#include <libutil.h>
#include <netdb.h>
+#include <nlist.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
@@ -106,6 +107,19 @@ struct bits {
{ 0 , 0 }
};
+/*
+ * kvm(3) bindings for every needed symbol
+ */
+static struct nlist rl[] = {
+#define N_RTSTAT 0
+ { .n_name = "_rtstat" },
+#define N_RTREE 1
+ { .n_name = "_rt_tables"},
+#define N_RTTRASH 2
+ { .n_name = "_rttrash" },
+ { .n_name = NULL },
+};
+
typedef union {
long dummy; /* Helps align structure. */
struct sockaddr u_sa;
@@ -151,9 +165,10 @@ static void domask(char *, in_addr_t, u_long);
* Print routing tables.
*/
void
-routepr(u_long rtree, int fibnum)
+routepr(int fibnum, int af)
{
struct radix_node_head **rnhp, *rnh, head;
+ u_long rtree;
size_t intsize;
int fam, numfibs;
@@ -165,10 +180,6 @@ routepr(u_long rtree, int fibnum)
numfibs = 1;
if (fibnum < 0 || fibnum > numfibs - 1)
errx(EX_USAGE, "%d: invalid fib", fibnum);
- rt_tables = calloc(numfibs * (AF_MAX+1),
- sizeof(struct radix_node_head *));
- if (rt_tables == NULL)
- err(EX_OSERR, "memory allocation failed");
/*
* Since kernel & userland use different timebase
* (time_uptime vs time_second) and we are reading kernel memory
@@ -182,14 +193,20 @@ routepr(u_long rtree, int fibnum)
printf(" (fib: %d)", fibnum);
printf("\n");
- if (Aflag == 0 && Mflag == 0 && NewTree)
+ if (Aflag == 0 && live != 0 && NewTree)
ntreestuff(fibnum, af);
else {
- if (rtree == 0) {
+ kresolve_list(rl);
+ if ((rtree = rl[N_RTREE].n_value) == 0) {
printf("rt_tables: symbol not in namelist\n");
return;
}
+ rt_tables = calloc(numfibs * (AF_MAX + 1),
+ sizeof(struct radix_node_head *));
+ if (rt_tables == NULL)
+ err(EX_OSERR, "memory allocation failed");
+
if (kread((u_long)(rtree), (char *)(rt_tables), (numfibs *
(AF_MAX+1) * sizeof(struct radix_node_head *))) != 0)
return;
@@ -572,14 +589,14 @@ ntreestuff(int fibnum, int af)
mib[5] = 0;
mib[6] = fibnum;
if (sysctl(mib, 7, NULL, &needed, NULL, 0) < 0) {
- err(1, "sysctl: net.route.0.0.dump estimate");
+ err(1, "sysctl: net.route.0.%d.dump.%d estimate", 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.0.dump");
+ err(1, "sysctl: net.route.0.%d.dump.%d", af, fibnum);
}
lim = buf + needed;
for (next = buf; next < lim; next += rtm->rtm_msglen) {
@@ -1071,16 +1088,19 @@ routename6(struct sockaddr_in6 *sa6)
* Print routing statistics
*/
void
-rt_stats(u_long rtsaddr, u_long rttaddr)
+rt_stats(void)
{
struct rtstat rtstat;
+ u_long rtsaddr, rttaddr;
int rttrash;
- if (rtsaddr == 0) {
+ kresolve_list(rl);
+
+ if ((rtsaddr = rl[N_RTSTAT].n_value) == 0) {
printf("rtstat: symbol not in namelist\n");
return;
}
- if (rttaddr == 0) {
+ if ((rttaddr = rl[N_RTTRASH].n_value) == 0) {
printf("rttrash: symbol not in namelist\n");
return;
}