summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/net/route.c20
-rw-r--r--sys/net/route.h22
-rw-r--r--sys/net/rtsock.c26
3 files changed, 54 insertions, 14 deletions
diff --git a/sys/net/route.c b/sys/net/route.c
index 66df750353a..3448bc360ba 100644
--- a/sys/net/route.c
+++ b/sys/net/route.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: route.c,v 1.346 2017/01/19 04:06:26 phessler Exp $ */
+/* $OpenBSD: route.c,v 1.347 2017/01/20 08:10:54 dlg Exp $ */
/* $NetBSD: route.c,v 1.14 1996/02/13 22:00:46 christos Exp $ */
/*
@@ -150,7 +150,7 @@ static uint32_t rt_hashjitter;
extern unsigned int rtmap_limit;
-struct rtstat rtstat;
+struct cpumem * rtcounters;
int rttrash; /* routes not in table but not freed */
int ifatrash; /* ifas not in ifp list but not free */
@@ -191,6 +191,8 @@ TAILQ_HEAD(rt_labels, rt_label) rt_labels = TAILQ_HEAD_INITIALIZER(rt_labels);
void
route_init(void)
{
+ rtcounters = counters_alloc(rts_ncounters, M_COUNTERS);
+
pool_init(&rtentry_pool, sizeof(struct rtentry), 0, IPL_SOFTNET, 0,
"rtentry", NULL);
@@ -273,7 +275,7 @@ rt_match(struct sockaddr *dst, uint32_t *src, int flags, unsigned int tableid)
}
rt->rt_use++;
} else
- rtstat.rts_unreach++;
+ rtstat_inc(rts_unreach);
return (rt);
}
@@ -545,7 +547,7 @@ rtredirect(struct sockaddr *dst, struct sockaddr *gateway,
{
struct rtentry *rt;
int error = 0;
- u_int32_t *stat = NULL;
+ enum rtstat_counters stat = rts_ncounters;
struct rt_addrinfo info;
struct ifaddr *ifa;
unsigned int ifidx = 0;
@@ -617,7 +619,7 @@ create:
flags = rt->rt_flags;
prio = rt->rt_priority;
}
- stat = &rtstat.rts_dynamic;
+ stat = rts_dynamic;
} else {
/*
* Smash the current notion of the gateway to
@@ -626,7 +628,7 @@ create:
rt->rt_flags |= RTF_MODIFIED;
flags |= RTF_MODIFIED;
prio = rt->rt_priority;
- stat = &rtstat.rts_newgateway;
+ stat = rts_newgateway;
rt_setgate(rt, gateway, rdomain);
}
} else
@@ -640,9 +642,9 @@ done:
}
out:
if (error)
- rtstat.rts_badredirect++;
- else if (stat != NULL)
- (*stat)++;
+ rtstat_inc(rts_badredirect);
+ else if (stat != rts_ncounters)
+ rtstat_inc(stat);
bzero((caddr_t)&info, sizeof(info));
info.rti_info[RTAX_DST] = dst;
info.rti_info[RTAX_GATEWAY] = gateway;
diff --git a/sys/net/route.h b/sys/net/route.h
index 660a91e465a..c64863dc08e 100644
--- a/sys/net/route.h
+++ b/sys/net/route.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: route.h,v 1.151 2017/01/19 23:18:29 phessler Exp $ */
+/* $OpenBSD: route.h,v 1.152 2017/01/20 08:10:54 dlg Exp $ */
/* $NetBSD: route.h,v 1.9 1996/02/13 22:00:49 christos Exp $ */
/*
@@ -319,6 +319,26 @@ struct rt_addrinfo {
#ifdef _KERNEL
+#include <sys/percpu.h>
+
+enum rtstat_counters {
+ rts_badredirect, /* bogus redirect calls */
+ rts_dynamic, /* routes created by redirects */
+ rts_newgateway, /* routes modified by redirects */
+ rts_unreach, /* lookups which failed */
+ rts_wildcard, /* lookups satisfied by a wildcard */
+
+ rts_ncounters
+};
+
+static inline void
+rtstat_inc(enum rtstat_counters c)
+{
+ extern struct cpumem *rtcounters;
+
+ counters_inc(rtcounters, c);
+}
+
/*
* This structure, and the prototypes for the rt_timer_{init,remove_all,
* add,timer} functions all used with the kind permission of BSDI.
diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c
index 7e6c0132bea..5abd9a015c0 100644
--- a/sys/net/rtsock.c
+++ b/sys/net/rtsock.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rtsock.c,v 1.213 2017/01/19 23:18:29 phessler Exp $ */
+/* $OpenBSD: rtsock.c,v 1.214 2017/01/20 08:10:54 dlg Exp $ */
/* $NetBSD: rtsock.c,v 1.18 1996/03/29 00:32:10 cgd Exp $ */
/*
@@ -111,6 +111,7 @@ void rt_xaddrs(caddr_t, caddr_t, struct rt_addrinfo *);
int sysctl_iflist(int, struct walkarg *);
int sysctl_ifnames(struct walkarg *);
+int sysctl_rtable_rtstat(void *, size_t *, void *);
struct routecb {
struct rawcb rcb;
@@ -1611,9 +1612,7 @@ sysctl_rtable(int *name, u_int namelen, void *where, size_t *given, void *new,
break;
case NET_RT_STATS:
- error = sysctl_rdstruct(where, given, new,
- &rtstat, sizeof(rtstat));
- return (error);
+ return (sysctl_rtable_rtstat(where, given, new));
case NET_RT_TABLE:
tableid = w.w_arg;
if (!rtable_exists(tableid))
@@ -1639,6 +1638,25 @@ sysctl_rtable(int *name, u_int namelen, void *where, size_t *given, void *new,
return (error);
}
+int
+sysctl_rtable_rtstat(void *oldp, size_t *oldlenp, void *newp)
+{
+ extern struct cpumem *rtcounters;
+ uint64_t counters[rts_ncounters];
+ struct rtstat rtstat;
+ uint32_t *words = (uint32_t *)&rtstat;
+ int i;
+
+ KASSERT(sizeof(rtstat) == (nitems(counters) * sizeof(uint32_t)));
+
+ counters_read(rtcounters, counters, nitems(counters));
+
+ for (i = 0; i < nitems(counters); i++)
+ words[i] = (uint32_t)counters[i];
+
+ return (sysctl_rdstruct(oldp, oldlenp, newp, &rtstat, sizeof(rtstat)));
+}
+
/*
* Definitions of protocols supported in the ROUTE domain.
*/