i didnt even know these existed.

turns out you can see them with netstat -sr

Index: route.c
===================================================================
RCS file: /cvs/src/sys/net/route.c,v
retrieving revision 1.338
diff -u -p -r1.338 route.c
--- route.c     15 Nov 2016 10:09:28 -0000      1.338
+++ route.c     18 Nov 2016 05:27:54 -0000
@@ -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 */
 
@@ -265,7 +265,7 @@ rt_match(struct sockaddr *dst, uint32_t 
                }
                rt->rt_use++;
        } else
-               rtstat.rts_unreach++;
+               rtstat_inc(rts_unreach);
        splx(s);
        return (rt);
 }
@@ -538,7 +538,7 @@ rtredirect(struct sockaddr *dst, struct 
 {
        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;
@@ -610,7 +610,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
@@ -619,7 +619,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
@@ -633,9 +633,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;
Index: route.h
===================================================================
RCS file: /cvs/src/sys/net/route.h,v
retrieving revision 1.148
diff -u -p -r1.148 route.h
--- route.h     24 Sep 2016 19:27:10 -0000      1.148
+++ route.h     18 Nov 2016 05:27:54 -0000
@@ -317,6 +317,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.
Index: rtsock.c
===================================================================
RCS file: /cvs/src/sys/net/rtsock.c,v
retrieving revision 1.208
diff -u -p -r1.208 rtsock.c
--- rtsock.c    18 Oct 2016 11:05:45 -0000      1.208
+++ rtsock.c    18 Nov 2016 05:27:54 -0000
@@ -111,6 +111,7 @@ void                 rt_xaddrs(caddr_t, caddr_t, struc
 
 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,10 +1612,8 @@ sysctl_rtable(int *name, u_int namelen, 
                break;
 
        case NET_RT_STATS:
-               error = sysctl_rdstruct(where, given, new,
-                   &rtstat, sizeof(rtstat));
                splx(s);
-               return (error);
+               return (sysctl_rtable_rtstat(where, given, new));
        case NET_RT_TABLE:
                tableid = w.w_arg;
                if (!rtable_exists(tableid)) {
@@ -1642,6 +1641,25 @@ sysctl_rtable(int *name, u_int namelen, 
                *given = (11 * w.w_needed) / 10;
 
        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;
+       u_long *words = (u_long *)&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)));
 }
 
 /*

Reply via email to