diff options
author | glebius <glebius@FreeBSD.org> | 2014-03-21 15:15:30 +0000 |
---|---|---|
committer | glebius <glebius@FreeBSD.org> | 2014-03-21 15:15:30 +0000 |
commit | 03fdc2934eb61c44c049a02b02aa974cfdd8a0eb (patch) | |
tree | cc0fec78da85e9575659f55226fa9d0d7e1fb82c | |
parent | a528b1ed30bfe465bfdd83f8e18449b8bf399429 (diff) | |
download | FreeBSD-src-03fdc2934eb61c44c049a02b02aa974cfdd8a0eb.zip FreeBSD-src-03fdc2934eb61c44c049a02b02aa974cfdd8a0eb.tar.gz |
Merge r262763, r262767, r262771, r262806 from head:
- Remove rt_metrics_lite and simply put its members into rtentry.
- Use counter(9) for rt_pksent (former rt_rmx.rmx_pksent). This
removes another cache trashing ++ from packet forwarding path.
- Create zini/fini methods for the rtentry UMA zone. Via initialize
mutex and counter in them.
- Fix reporting of rmx_pksent to routing socket.
- Fix netstat(1) to report "Use" both in kvm(3) and sysctl(3) mode.
30 files changed, 195 insertions, 171 deletions
diff --git a/share/man/man9/rtentry.9 b/share/man/man9/rtentry.9 index d7e6953..12fa93d 100644 --- a/share/man/man9/rtentry.9 +++ b/share/man/man9/rtentry.9 @@ -28,7 +28,7 @@ .\" .\" $FreeBSD$ .\" -.Dd December 11, 2008 +.Dd March 5, 2014 .Dt RTENTRY 9 .Os .Sh NAME @@ -78,6 +78,12 @@ intermediate stop on the way to that destination (if the flag is set). .It Vt "int rt_flags" ; See below. +If the +.Dv RTF_UP +flag is not present, the +.Fn rtfree +function will delete the route from the radix tree when the last +reference drops. .It Vt "int rt_refcnt" ; Route entries are reference-counted; this field indicates the number of external (to the radix tree) references. @@ -89,14 +95,14 @@ as it were, to the question posed by a route lookup; that is, they name the interface and interface address to be used in sending a packet to the destination or set of destinations which this route represents. -.It Vt "struct rt_metrics_lite rt_rmx" ; -See below. -If the -.Dv RTF_UP -flag is not present, the -.Fn rtfree -function will delete the route from the radix tree when the last -reference drops. +.It Vt "u_long rt_mtu"; +See description of rmx_mtu below. +.It Vt "u_long rt_weight"; +See description of rmx_weight below. +.It Vt "u_long rt_expire"; +See description of rmx_expire below. +.It Vt "counter64_t rt_pksent"; +See description of rmx_pksent below. .It Vt "struct rtentry *rt_gwroute" ; This member is a reference to a route whose destination is .Va rt_gateway . @@ -165,9 +171,7 @@ Indicates that the destination is a broadcast address. Indicates that the destination is a multicast address. .El .Pp -Every route has associated with it a set of metrics, stored in -.Vt "struct rt_metrics_lite" . -Metrics are supplied in +Several metrics are supplied in .Vt "struct rt_metrics" passed with routing control messages via .Xr route 4 @@ -176,8 +180,7 @@ Currently only .Vt rmx_mtu , rmx_expire , and .Vt rmx_pksent -metrics are used in -.Vt "struct rt_metrics_lite" . +metrics are supplied. All others are ignored. .Pp The following metrics are defined by diff --git a/sys/contrib/ipfilter/netinet/ip_fil_freebsd.c b/sys/contrib/ipfilter/netinet/ip_fil_freebsd.c index 898869a..10e9de7 100644 --- a/sys/contrib/ipfilter/netinet/ip_fil_freebsd.c +++ b/sys/contrib/ipfilter/netinet/ip_fil_freebsd.c @@ -802,7 +802,7 @@ ipf_fastroute(m0, mpp, fin, fdp) if (ro->ro_rt->rt_flags & RTF_GATEWAY) dst = (struct sockaddr_in *)ro->ro_rt->rt_gateway; if (ro->ro_rt) - ro->ro_rt->rt_use++; + counter_u64_add(ro->ro_rt->rt_pksent, 1); /* * For input packets which are being "fastrouted", they won't diff --git a/sys/net/if_disc.c b/sys/net/if_disc.c index 16a1e7b..d072e4d 100644 --- a/sys/net/if_disc.c +++ b/sys/net/if_disc.c @@ -185,7 +185,7 @@ static void discrtrequest(int cmd, struct rtentry *rt, struct rt_addrinfo *info) { RT_LOCK_ASSERT(rt); - rt->rt_rmx.rmx_mtu = DSMTU; + rt->rt_mtu = DSMTU; } /* diff --git a/sys/net/if_faith.c b/sys/net/if_faith.c index 37a53bb..fb98f41 100644 --- a/sys/net/if_faith.c +++ b/sys/net/if_faith.c @@ -245,7 +245,7 @@ faithrtrequest(cmd, rt, info) struct rt_addrinfo *info; { RT_LOCK_ASSERT(rt); - rt->rt_rmx.rmx_mtu = rt->rt_ifp->if_mtu; + rt->rt_mtu = rt->rt_ifp->if_mtu; } /* diff --git a/sys/net/if_loop.c b/sys/net/if_loop.c index 499cd2c..e17fa11 100644 --- a/sys/net/if_loop.c +++ b/sys/net/if_loop.c @@ -394,7 +394,7 @@ lortrequest(int cmd, struct rtentry *rt, struct rt_addrinfo *info) { RT_LOCK_ASSERT(rt); - rt->rt_rmx.rmx_mtu = rt->rt_ifp->if_mtu; + rt->rt_mtu = rt->rt_ifp->if_mtu; } /* diff --git a/sys/net/if_stf.c b/sys/net/if_stf.c index 2c34739..20251dc 100644 --- a/sys/net/if_stf.c +++ b/sys/net/if_stf.c @@ -784,7 +784,7 @@ stf_rtrequest(cmd, rt, info) struct rt_addrinfo *info; { RT_LOCK_ASSERT(rt); - rt->rt_rmx.rmx_mtu = rt->rt_ifp->if_mtu; + rt->rt_mtu = rt->rt_ifp->if_mtu; } static int diff --git a/sys/net/radix_mpath.c b/sys/net/radix_mpath.c index ee7826f..c87f13c 100644 --- a/sys/net/radix_mpath.c +++ b/sys/net/radix_mpath.c @@ -85,7 +85,7 @@ rn_mpath_count(struct radix_node *rn) while (rn != NULL) { rt = (struct rtentry *)rn; - i += rt->rt_rmx.rmx_weight; + i += rt->rt_weight; rn = rn_mpath_next(rn); } return (i); @@ -288,8 +288,8 @@ rtalloc_mpath_fib(struct route *ro, uint32_t hash, u_int fibnum) hash += hashjitter; hash %= n; for (weight = abs((int32_t)hash), rt = ro->ro_rt; - weight >= rt->rt_rmx.rmx_weight && rn; - weight -= rt->rt_rmx.rmx_weight) { + weight >= rt->rt_weight && rn; + weight -= rt->rt_weight) { /* stay within the multipath routes */ if (rn->rn_dupedkey && rn->rn_mask != rn->rn_dupedkey->rn_mask) diff --git a/sys/net/route.c b/sys/net/route.c index bb99496..e546e20 100644 --- a/sys/net/route.c +++ b/sys/net/route.c @@ -200,6 +200,48 @@ route_init(void) } SYSINIT(route_init, SI_SUB_PROTO_DOMAIN, SI_ORDER_THIRD, route_init, 0); +static int +rtentry_zinit(void *mem, int size, int how) +{ + struct rtentry *rt = mem; + + rt->rt_pksent = counter_u64_alloc(how); + if (rt->rt_pksent == NULL) + return (ENOMEM); + + RT_LOCK_INIT(rt); + + return (0); +} + +static void +rtentry_zfini(void *mem, int size) +{ + struct rtentry *rt = mem; + + RT_LOCK_DESTROY(rt); + counter_u64_free(rt->rt_pksent); +} + +static int +rtentry_ctor(void *mem, int size, void *arg, int how) +{ + struct rtentry *rt = mem; + + bzero(rt, offsetof(struct rtentry, rt_endzero)); + counter_u64_zero(rt->rt_pksent); + + return (0); +} + +static void +rtentry_dtor(void *mem, int size, void *arg) +{ + struct rtentry *rt = mem; + + RT_UNLOCK_COND(rt); +} + static void vnet_route_init(const void *unused __unused) { @@ -211,8 +253,9 @@ vnet_route_init(const void *unused __unused) V_rt_tables = malloc(rt_numfibs * (AF_MAX+1) * sizeof(struct radix_node_head *), M_RTABLE, M_WAITOK|M_ZERO); - V_rtzone = uma_zcreate("rtentry", sizeof(struct rtentry), NULL, NULL, - NULL, NULL, UMA_ALIGN_PTR, 0); + V_rtzone = uma_zcreate("rtentry", sizeof(struct rtentry), + rtentry_ctor, rtentry_dtor, + rtentry_zinit, rtentry_zfini, UMA_ALIGN_PTR, 0); for (dom = domains; dom; dom = dom->dom_next) { if (dom->dom_rtattach == NULL) continue; @@ -489,7 +532,6 @@ rtfree(struct rtentry *rt) /* * and the rtentry itself of course */ - RT_LOCK_DESTROY(rt); uma_zfree(V_rtzone, rt); return; } @@ -1173,12 +1215,11 @@ rtrequest1_fib(int req, struct rt_addrinfo *info, struct rtentry **ret_nrt, } else ifa_ref(info->rti_ifa); ifa = info->rti_ifa; - rt = uma_zalloc(V_rtzone, M_NOWAIT | M_ZERO); + rt = uma_zalloc(V_rtzone, M_NOWAIT); if (rt == NULL) { ifa_free(ifa); senderr(ENOBUFS); } - RT_LOCK_INIT(rt); rt->rt_flags = RTF_UP | flags; rt->rt_fibnum = fibnum; /* @@ -1186,7 +1227,6 @@ rtrequest1_fib(int req, struct rt_addrinfo *info, struct rtentry **ret_nrt, */ RT_LOCK(rt); if ((error = rt_setgate(rt, dst, gateway)) != 0) { - RT_LOCK_DESTROY(rt); ifa_free(ifa); uma_zfree(V_rtzone, rt); senderr(error); @@ -1212,7 +1252,7 @@ rtrequest1_fib(int req, struct rt_addrinfo *info, struct rtentry **ret_nrt, */ rt->rt_ifa = ifa; rt->rt_ifp = ifa->ifa_ifp; - rt->rt_rmx.rmx_weight = 1; + rt->rt_weight = 1; #ifdef RADIX_MPATH /* do not permit exactly the same dst/mask/gw pair */ @@ -1220,7 +1260,6 @@ rtrequest1_fib(int req, struct rt_addrinfo *info, struct rtentry **ret_nrt, rt_mpath_conflict(rnh, rt, netmask)) { ifa_free(rt->rt_ifa); Free(rt_key(rt)); - RT_LOCK_DESTROY(rt); uma_zfree(V_rtzone, rt); senderr(EEXIST); } @@ -1288,7 +1327,6 @@ rtrequest1_fib(int req, struct rt_addrinfo *info, struct rtentry **ret_nrt, if (rn == NULL) { ifa_free(rt->rt_ifa); Free(rt_key(rt)); - RT_LOCK_DESTROY(rt); uma_zfree(V_rtzone, rt); #ifdef FLOWTABLE if (rt0 != NULL) diff --git a/sys/net/route.h b/sys/net/route.h index 02d0ae9..a9fcbd0 100644 --- a/sys/net/route.h +++ b/sys/net/route.h @@ -33,6 +33,8 @@ #ifndef _NET_ROUTE_H_ #define _NET_ROUTE_H_ +#include <sys/counter.h> + /* * Kernel resident routing tables. * @@ -57,17 +59,6 @@ struct route { #define RT_CACHING_CONTEXT 0x1 /* XXX: not used anywhere */ #define RT_NORTREF 0x2 /* doesn't hold reference on ro_rt */ -/* - * These numbers are used by reliable protocols for determining - * retransmission behavior and are included in the routing structure. - */ -struct rt_metrics_lite { - u_long rmx_mtu; /* MTU for this path */ - u_long rmx_expire; /* lifetime for route, e.g. redirect */ - u_long rmx_pksent; /* packets sent using this route */ - u_long rmx_weight; /* absolute weight */ -}; - struct rt_metrics { u_long rmx_locks; /* Kernel must leave these values alone */ u_long rmx_mtu; /* MTU for this path */ @@ -112,6 +103,8 @@ struct mbuf; #include <net/radix_mpath.h> #endif #endif + +#if defined(_KERNEL) || defined(_WANT_RTENTRY) struct rtentry { struct radix_node rt_nodes[2]; /* tree glue, and other values */ /* @@ -122,17 +115,19 @@ struct rtentry { #define rt_key(r) (*((struct sockaddr **)(&(r)->rt_nodes->rn_key))) #define rt_mask(r) (*((struct sockaddr **)(&(r)->rt_nodes->rn_mask))) struct sockaddr *rt_gateway; /* value */ - int rt_flags; /* up/down?, host/net */ - int rt_refcnt; /* # held references */ struct ifnet *rt_ifp; /* the answer: interface to use */ struct ifaddr *rt_ifa; /* the answer: interface address to use */ - struct rt_metrics_lite rt_rmx; /* metrics used by rx'ing protocols */ - u_int rt_fibnum; /* which FIB */ -#ifdef _KERNEL - /* XXX ugly, user apps use this definition but don't have a mtx def */ - struct mtx rt_mtx; /* mutex for routing entry */ -#endif + int rt_flags; /* up/down?, host/net */ + int rt_refcnt; /* # held references */ + u_int rt_fibnum; /* which FIB */ + u_long rt_mtu; /* MTU for this path */ + u_long rt_weight; /* absolute weight */ + u_long rt_expire; /* lifetime for route, e.g. redirect */ +#define rt_endzero rt_pksent + counter_u64_t rt_pksent; /* packets sent using this route */ + struct mtx rt_mtx; /* mutex for routing entry */ }; +#endif /* _KERNEL || _WANT_RTENTRY */ /* * Following structure necessary for 4.3 compatibility; @@ -148,8 +143,6 @@ struct ortentry { struct ifnet *rt_ifp; /* the answer: interface to use */ }; -#define rt_use rt_rmx.rmx_pksent - #define RTF_UP 0x1 /* route usable */ #define RTF_GATEWAY 0x2 /* destination is a gateway */ #define RTF_HOST 0x4 /* host entry (net otherwise) */ @@ -314,6 +307,10 @@ struct rt_addrinfo { #define RT_UNLOCK(_rt) mtx_unlock(&(_rt)->rt_mtx) #define RT_LOCK_DESTROY(_rt) mtx_destroy(&(_rt)->rt_mtx) #define RT_LOCK_ASSERT(_rt) mtx_assert(&(_rt)->rt_mtx, MA_OWNED) +#define RT_UNLOCK_COND(_rt) do { \ + if (mtx_owned(&(_rt)->rt_mtx)) \ + mtx_unlock(&(_rt)->rt_mtx); \ +} while (0) #define RT_ADDREF(_rt) do { \ RT_LOCK_ASSERT(_rt); \ diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c index 0b5d1c5..b65b5eb 100644 --- a/sys/net/rtsock.c +++ b/sys/net/rtsock.c @@ -194,10 +194,8 @@ static int sysctl_dumpentry(struct radix_node *rn, void *vw); static int sysctl_iflist(int af, struct walkarg *w); static int sysctl_ifmalist(int af, struct walkarg *w); static int route_output(struct mbuf *m, struct socket *so); -static void rt_setmetrics(u_long which, const struct rt_metrics *in, - struct rt_metrics_lite *out); -static void rt_getmetrics(const struct rt_metrics_lite *in, - struct rt_metrics *out); +static void rt_setmetrics(const struct rt_msghdr *rtm, struct rtentry *rt); +static void rt_getmetrics(const struct rtentry *rt, struct rt_metrics *out); static void rt_dispatch(struct mbuf *, sa_family_t); static struct netisr_handler rtsock_nh = { @@ -685,8 +683,7 @@ route_output(struct mbuf *m, struct socket *so) rti_need_deembed = (V_deembed_scopeid) ? 1 : 0; #endif RT_LOCK(saved_nrt); - rt_setmetrics(rtm->rtm_inits, - &rtm->rtm_rmx, &saved_nrt->rt_rmx); + rt_setmetrics(rtm, saved_nrt); rtm->rtm_index = saved_nrt->rt_ifp->if_index; RT_REMREF(saved_nrt); RT_UNLOCK(saved_nrt); @@ -860,7 +857,7 @@ route_output(struct mbuf *m, struct socket *so) (rt->rt_flags & ~RTF_GWFLAG_COMPAT); else rtm->rtm_flags = rt->rt_flags; - rt_getmetrics(&rt->rt_rmx, &rtm->rtm_rmx); + rt_getmetrics(rt, &rtm->rtm_rmx); rtm->rtm_addrs = info.rti_addrs; break; @@ -923,8 +920,7 @@ route_output(struct mbuf *m, struct socket *so) /* Allow some flags to be toggled on change. */ rt->rt_flags = (rt->rt_flags & ~RTF_FMASK) | (rtm->rtm_flags & RTF_FMASK); - rt_setmetrics(rtm->rtm_inits, &rtm->rtm_rmx, - &rt->rt_rmx); + rt_setmetrics(rtm, rt); rtm->rtm_index = rt->rt_ifp->if_index; if (rt->rt_ifa && rt->rt_ifa->ifa_rtrequest) rt->rt_ifa->ifa_rtrequest(RTM_ADD, rt, &info); @@ -1012,34 +1008,30 @@ flush: } static void -rt_setmetrics(u_long which, const struct rt_metrics *in, - struct rt_metrics_lite *out) +rt_setmetrics(const struct rt_msghdr *rtm, struct rtentry *rt) { -#define metric(f, e) if (which & (f)) out->e = in->e; - /* - * Only these are stored in the routing entry since introduction - * of tcp hostcache. The rest is ignored. - */ - metric(RTV_MTU, rmx_mtu); - metric(RTV_WEIGHT, rmx_weight); - /* Userland -> kernel timebase conversion. */ - if (which & RTV_EXPIRE) - out->rmx_expire = in->rmx_expire ? - in->rmx_expire - time_second + time_uptime : 0; -#undef metric + + if (rtm->rtm_inits & RTV_MTU) + rt->rt_mtu = rtm->rtm_rmx.rmx_mtu; + if (rtm->rtm_inits & RTV_WEIGHT) + rt->rt_weight = rtm->rtm_rmx.rmx_weight; + /* Kernel -> userland timebase conversion. */ + if (rtm->rtm_inits & RTV_EXPIRE) + rt->rt_expire = rtm->rtm_rmx.rmx_expire ? + rtm->rtm_rmx.rmx_expire - time_second + time_uptime : 0; } static void -rt_getmetrics(const struct rt_metrics_lite *in, struct rt_metrics *out) +rt_getmetrics(const struct rtentry *rt, struct rt_metrics *out) { -#define metric(e) out->e = in->e; + bzero(out, sizeof(*out)); - metric(rmx_mtu); - metric(rmx_weight); + out->rmx_mtu = rt->rt_mtu; + out->rmx_weight = rt->rt_weight; + out->rmx_pksent = counter_u64_fetch(rt->rt_pksent); /* Kernel -> userland timebase conversion. */ - out->rmx_expire = in->rmx_expire ? - in->rmx_expire - time_uptime + time_second : 0; -#undef metric + out->rmx_expire = rt->rt_expire ? + rt->rt_expire - time_uptime + time_second : 0; } /* @@ -1603,11 +1595,7 @@ sysctl_dumpentry(struct radix_node *rn, void *vw) (rt->rt_flags & ~RTF_GWFLAG_COMPAT); else rtm->rtm_flags = rt->rt_flags; - /* - * let's be honest about this being a retarded hack - */ - rtm->rtm_fmask = rt->rt_rmx.rmx_pksent; - rt_getmetrics(&rt->rt_rmx, &rtm->rtm_rmx); + rt_getmetrics(rt, &rtm->rtm_rmx); rtm->rtm_index = rt->rt_ifp->if_index; rtm->rtm_errno = rtm->rtm_pid = rtm->rtm_seq = 0; rtm->rtm_addrs = info.rti_addrs; diff --git a/sys/netatalk/at_proto.c b/sys/netatalk/at_proto.c index f62df59..00eb4eb 100644 --- a/sys/netatalk/at_proto.c +++ b/sys/netatalk/at_proto.c @@ -24,6 +24,7 @@ */ #include <sys/param.h> +#include <sys/systm.h> #include <sys/protosw.h> #include <sys/domain.h> #include <sys/socket.h> diff --git a/sys/netatalk/ddp_output.c b/sys/netatalk/ddp_output.c index 2b53de4..c52df96 100644 --- a/sys/netatalk/ddp_output.c +++ b/sys/netatalk/ddp_output.c @@ -221,7 +221,7 @@ ddp_route(struct mbuf *m, struct route *ro) elh->el_type = ELAP_DDPEXTEND; elh->el_dnode = gate.sat_addr.s_node; } - ro->ro_rt->rt_use++; + counter_u64_add(ro->ro_rt->rt_pksent, 1); #ifdef NETATALK_DEBUG printf ("ddp_route: from %d.%d to %d.%d, via %d.%d (%s)\n", diff --git a/sys/netinet/in_rmx.c b/sys/netinet/in_rmx.c index d09805d..9b89fbd 100644 --- a/sys/netinet/in_rmx.c +++ b/sys/netinet/in_rmx.c @@ -93,8 +93,8 @@ in_addroute(void *v_arg, void *n_arg, struct radix_node_head *head, if (IN_MULTICAST(ntohl(sin->sin_addr.s_addr))) rt->rt_flags |= RTF_MULTICAST; - if (!rt->rt_rmx.rmx_mtu && rt->rt_ifp) - rt->rt_rmx.rmx_mtu = rt->rt_ifp->if_mtu; + if (rt->rt_mtu == 0 && rt->rt_ifp != NULL) + rt->rt_mtu = rt->rt_ifp->if_mtu; return (rn_addroute(v_arg, n_arg, head, treenodes)); } @@ -114,7 +114,7 @@ in_matroute(void *v_arg, struct radix_node_head *head) RT_LOCK(rt); if (rt->rt_flags & RTPRF_OURS) { rt->rt_flags &= ~RTPRF_OURS; - rt->rt_rmx.rmx_expire = 0; + rt->rt_expire = 0; } RT_UNLOCK(rt); } @@ -167,7 +167,7 @@ in_clsroute(struct radix_node *rn, struct radix_node_head *head) */ if (V_rtq_reallyold != 0) { rt->rt_flags |= RTPRF_OURS; - rt->rt_rmx.rmx_expire = time_uptime + V_rtq_reallyold; + rt->rt_expire = time_uptime + V_rtq_reallyold; } else { rtexpunge(rt); } @@ -199,7 +199,7 @@ in_rtqkill(struct radix_node *rn, void *rock) if (rt->rt_flags & RTPRF_OURS) { ap->found++; - if (ap->draining || rt->rt_rmx.rmx_expire <= time_uptime) { + if (ap->draining || rt->rt_expire <= time_uptime) { if (rt->rt_refcnt > 0) panic("rtqkill route really not free"); @@ -215,13 +215,9 @@ in_rtqkill(struct radix_node *rn, void *rock) } } else { if (ap->updating && - (rt->rt_rmx.rmx_expire - time_uptime > - V_rtq_reallyold)) { - rt->rt_rmx.rmx_expire = - time_uptime + V_rtq_reallyold; - } - ap->nextstop = lmin(ap->nextstop, - rt->rt_rmx.rmx_expire); + (rt->rt_expire - time_uptime > V_rtq_reallyold)) + rt->rt_expire = time_uptime + V_rtq_reallyold; + ap->nextstop = lmin(ap->nextstop, rt->rt_expire); } } diff --git a/sys/netinet/ip_fastfwd.c b/sys/netinet/ip_fastfwd.c index 7d81475..c5405d5 100644 --- a/sys/netinet/ip_fastfwd.c +++ b/sys/netinet/ip_fastfwd.c @@ -491,8 +491,7 @@ passout: * Check if route is dampned (when ARP is unable to resolve) */ if ((ro.ro_rt->rt_flags & RTF_REJECT) && - (ro.ro_rt->rt_rmx.rmx_expire == 0 || - time_uptime < ro.ro_rt->rt_rmx.rmx_expire)) { + (ro.ro_rt->rt_expire == 0 || time_uptime < ro.ro_rt->rt_expire)) { icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_HOST, 0, 0); goto consumed; } @@ -520,8 +519,8 @@ passout: /* * Check if packet fits MTU or if hardware will fragment for us */ - if (ro.ro_rt->rt_rmx.rmx_mtu) - mtu = min(ro.ro_rt->rt_rmx.rmx_mtu, ifp->if_mtu); + if (ro.ro_rt->rt_mtu) + mtu = min(ro.ro_rt->rt_mtu, ifp->if_mtu); else mtu = ifp->if_mtu; @@ -586,7 +585,7 @@ passout: if (error != 0) IPSTAT_INC(ips_odropped); else { - ro.ro_rt->rt_rmx.rmx_pksent++; + counter_u64_add(ro.ro_rt->rt_pksent, 1); IPSTAT_INC(ips_forward); IPSTAT_INC(ips_fastforward); } diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c index 49281d5..26b9dfa 100644 --- a/sys/netinet/ip_input.c +++ b/sys/netinet/ip_input.c @@ -1471,7 +1471,7 @@ ip_forward(struct mbuf *m, int srcrt) error = ip_output(m, NULL, &ro, IP_FORWARDING, NULL, NULL); if (error == EMSGSIZE && ro.ro_rt) - mtu = ro.ro_rt->rt_rmx.rmx_mtu; + mtu = ro.ro_rt->rt_mtu; RO_RTFREE(&ro); if (error) diff --git a/sys/netinet/ip_ipsec.c b/sys/netinet/ip_ipsec.c index 526a6de..28b899d 100644 --- a/sys/netinet/ip_ipsec.c +++ b/sys/netinet/ip_ipsec.c @@ -236,9 +236,7 @@ ip_ipsec_mtu(struct mbuf *m, int mtu) sp->req->sav->sah != NULL) { ro = &sp->req->sav->sah->route_cache.sa_route; if (ro->ro_rt && ro->ro_rt->rt_ifp) { - mtu = - ro->ro_rt->rt_rmx.rmx_mtu ? - ro->ro_rt->rt_rmx.rmx_mtu : + mtu = ro->ro_rt->rt_mtu ? ro->ro_rt->rt_mtu : ro->ro_rt->rt_ifp->if_mtu; mtu -= ipsechdr; } diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c index bee37a7..69832d4 100644 --- a/sys/netinet/ip_output.c +++ b/sys/netinet/ip_output.c @@ -296,7 +296,7 @@ again: } ia = ifatoia(rte->rt_ifa); ifp = rte->rt_ifp; - rte->rt_rmx.rmx_pksent++; + counter_u64_add(rte->rt_pksent, 1); if (rte->rt_flags & RTF_GATEWAY) gw = (struct sockaddr_in *)rte->rt_gateway; if (rte->rt_flags & RTF_HOST) @@ -316,9 +316,9 @@ again: * them, there is no way for one to update all its * routes when the MTU is changed. */ - if (rte->rt_rmx.rmx_mtu > ifp->if_mtu) - rte->rt_rmx.rmx_mtu = ifp->if_mtu; - mtu = rte->rt_rmx.rmx_mtu; + if (rte->rt_mtu > ifp->if_mtu) + rte->rt_mtu = ifp->if_mtu; + mtu = rte->rt_mtu; } else { mtu = ifp->if_mtu; } diff --git a/sys/netinet/sctp_os_bsd.h b/sys/netinet/sctp_os_bsd.h index 2159bbc..855b411 100644 --- a/sys/netinet/sctp_os_bsd.h +++ b/sys/netinet/sctp_os_bsd.h @@ -328,11 +328,11 @@ typedef struct callout sctp_os_timer_t; /* MTU */ /*************************/ #define SCTP_GATHER_MTU_FROM_IFN_INFO(ifn, ifn_index, af) ((struct ifnet *)ifn)->if_mtu -#define SCTP_GATHER_MTU_FROM_ROUTE(sctp_ifa, sa, rt) ((rt != NULL) ? rt->rt_rmx.rmx_mtu : 0) +#define SCTP_GATHER_MTU_FROM_ROUTE(sctp_ifa, sa, rt) ((rt != NULL) ? rt->rt_mtu : 0) #define SCTP_GATHER_MTU_FROM_INTFC(sctp_ifn) ((sctp_ifn->ifn_p != NULL) ? ((struct ifnet *)(sctp_ifn->ifn_p))->if_mtu : 0) #define SCTP_SET_MTU_OF_ROUTE(sa, rt, mtu) do { \ if (rt != NULL) \ - rt->rt_rmx.rmx_mtu = mtu; \ + rt->rt_mtu = mtu; \ } while(0) /* (de-)register interface event notifications */ diff --git a/sys/netinet/tcp_output.c b/sys/netinet/tcp_output.c index f80a20e..8c97c12 100644 --- a/sys/netinet/tcp_output.c +++ b/sys/netinet/tcp_output.c @@ -1195,7 +1195,7 @@ send: NULL, NULL, tp->t_inpcb); if (error == EMSGSIZE && ro.ro_rt != NULL) - mtu = ro.ro_rt->rt_rmx.rmx_mtu; + mtu = ro.ro_rt->rt_mtu; RO_RTFREE(&ro); } #endif /* INET6 */ @@ -1233,7 +1233,7 @@ send: tp->t_inpcb); if (error == EMSGSIZE && ro.ro_rt != NULL) - mtu = ro.ro_rt->rt_rmx.rmx_mtu; + mtu = ro.ro_rt->rt_mtu; RO_RTFREE(&ro); } #endif /* INET */ diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c index 2400c80..4a9cece 100644 --- a/sys/netinet/tcp_subr.c +++ b/sys/netinet/tcp_subr.c @@ -1797,10 +1797,10 @@ tcp_maxmtu(struct in_conninfo *inc, struct tcp_ifcap *cap) } if (sro.ro_rt != NULL) { ifp = sro.ro_rt->rt_ifp; - if (sro.ro_rt->rt_rmx.rmx_mtu == 0) + if (sro.ro_rt->rt_mtu == 0) maxmtu = ifp->if_mtu; else - maxmtu = min(sro.ro_rt->rt_rmx.rmx_mtu, ifp->if_mtu); + maxmtu = min(sro.ro_rt->rt_mtu, ifp->if_mtu); /* Report additional interface capabilities. */ if (cap != NULL) { @@ -1834,10 +1834,10 @@ tcp_maxmtu6(struct in_conninfo *inc, struct tcp_ifcap *cap) } if (sro6.ro_rt != NULL) { ifp = sro6.ro_rt->rt_ifp; - if (sro6.ro_rt->rt_rmx.rmx_mtu == 0) + if (sro6.ro_rt->rt_mtu == 0) maxmtu = IN6_LINKMTU(sro6.ro_rt->rt_ifp); else - maxmtu = min(sro6.ro_rt->rt_rmx.rmx_mtu, + maxmtu = min(sro6.ro_rt->rt_mtu, IN6_LINKMTU(sro6.ro_rt->rt_ifp)); /* Report additional interface capabilities. */ diff --git a/sys/netinet6/in6_rmx.c b/sys/netinet6/in6_rmx.c index 88ecc14..394cdb6 100644 --- a/sys/netinet6/in6_rmx.c +++ b/sys/netinet6/in6_rmx.c @@ -135,8 +135,8 @@ in6_addroute(void *v_arg, void *n_arg, struct radix_node_head *head, } } - if (!rt->rt_rmx.rmx_mtu && rt->rt_ifp) - rt->rt_rmx.rmx_mtu = IN6_LINKMTU(rt->rt_ifp); + if (!rt->rt_mtu && rt->rt_ifp) + rt->rt_mtu = IN6_LINKMTU(rt->rt_ifp); ret = rn_addroute(v_arg, n_arg, head, treenodes); if (ret == NULL) { @@ -206,12 +206,11 @@ in6_mtuexpire(struct radix_node *rn, void *rock) if (!rt) panic("rt == NULL in in6_mtuexpire"); - if (rt->rt_rmx.rmx_expire && !(rt->rt_flags & RTF_PROBEMTU)) { - if (rt->rt_rmx.rmx_expire <= time_uptime) { + if (rt->rt_expire && !(rt->rt_flags & RTF_PROBEMTU)) { + if (rt->rt_expire <= time_uptime) { rt->rt_flags |= RTF_PROBEMTU; } else { - ap->nextstop = lmin(ap->nextstop, - rt->rt_rmx.rmx_expire); + ap->nextstop = lmin(ap->nextstop, rt->rt_expire); } } diff --git a/sys/netinet6/ip6_ipsec.c b/sys/netinet6/ip6_ipsec.c index 8cdd431..436af00 100644 --- a/sys/netinet6/ip6_ipsec.c +++ b/sys/netinet6/ip6_ipsec.c @@ -369,9 +369,7 @@ ip6_ipsec_mtu(struct mbuf *m) sp->req->sav->sah != NULL) { ro = &sp->req->sav->sah->route_cache.sa_route; if (ro->ro_rt && ro->ro_rt->rt_ifp) { - mtu = - ro->ro_rt->rt_rmx.rmx_mtu ? - ro->ro_rt->rt_rmx.rmx_mtu : + mtu = ro->ro_rt->rt_mtu ? ro->ro_rt->rt_mtu : ro->ro_rt->rt_ifp->if_mtu; mtu -= ipsechdr; } diff --git a/sys/netinet6/ip6_output.c b/sys/netinet6/ip6_output.c index 171a918..b1d27d4 100644 --- a/sys/netinet6/ip6_output.c +++ b/sys/netinet6/ip6_output.c @@ -218,9 +218,9 @@ in6_delayed_cksum(struct mbuf *m, uint32_t plen, u_short offset) * skipped and ro->ro_rt would be used. If ro is present but ro->ro_rt is NULL, * then result of route lookup is stored in ro->ro_rt. * - * type of "mtu": rt_rmx.rmx_mtu is u_long, ifnet.ifr_mtu is int, and + * type of "mtu": rt_mtu is u_long, ifnet.ifr_mtu is int, and * nd_ifinfo.linkmtu is u_int32_t. so we use u_long to hold largest one, - * which is rt_rmx.rmx_mtu. + * which is rt_mtu. * * ifpp - XXX: just for statistics */ @@ -660,7 +660,7 @@ again: } if (rt != NULL) { ia = (struct in6_ifaddr *)(rt->rt_ifa); - rt->rt_use++; + counter_u64_add(rt->rt_pksent, 1); } @@ -1396,9 +1396,9 @@ ip6_getpmtu(struct route_in6 *ro_pmtu, struct route_in6 *ro, ifmtu = IN6_LINKMTU(ifp); mtu = tcp_hc_getmtu(&inc); if (mtu) - mtu = min(mtu, ro_pmtu->ro_rt->rt_rmx.rmx_mtu); + mtu = min(mtu, ro_pmtu->ro_rt->rt_mtu); else - mtu = ro_pmtu->ro_rt->rt_rmx.rmx_mtu; + mtu = ro_pmtu->ro_rt->rt_mtu; if (mtu == 0) mtu = ifmtu; else if (mtu < IPV6_MMTU) { @@ -1422,7 +1422,7 @@ ip6_getpmtu(struct route_in6 *ro_pmtu, struct route_in6 *ro, * field isn't locked). */ mtu = ifmtu; - ro_pmtu->ro_rt->rt_rmx.rmx_mtu = mtu; + ro_pmtu->ro_rt->rt_mtu = mtu; } } else if (ifp) { mtu = IN6_LINKMTU(ifp); diff --git a/sys/netipx/ipx_input.c b/sys/netipx/ipx_input.c index 9d44ec5..6b6e352 100644 --- a/sys/netipx/ipx_input.c +++ b/sys/netipx/ipx_input.c @@ -454,7 +454,7 @@ ipx_do_route(struct ipx_addr *src, struct route *ro) if (ro->ro_rt == NULL || ro->ro_rt->rt_ifp == NULL) { return (0); } - ro->ro_rt->rt_use++; + counter_u64_add(ro->ro_rt->rt_pksent, 1); return (1); } diff --git a/sys/netipx/ipx_outputfl.c b/sys/netipx/ipx_outputfl.c index 25bbedf..550eeb2 100644 --- a/sys/netipx/ipx_outputfl.c +++ b/sys/netipx/ipx_outputfl.c @@ -129,7 +129,7 @@ ipx_outputfl(struct mbuf *m0, struct route *ro, int flags) error = ENETUNREACH; goto bad; } - ro->ro_rt->rt_use++; + counter_u64_add(ro->ro_rt->rt_pksent, 1); if (ro->ro_rt->rt_flags & (RTF_GATEWAY|RTF_HOST)) dst = (struct sockaddr_ipx *)ro->ro_rt->rt_gateway; gotif: diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c index cef5352..f701425 100644 --- a/sys/netpfil/pf/pf.c +++ b/sys/netpfil/pf/pf.c @@ -5267,7 +5267,7 @@ pf_route(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp, } ifp = rt->rt_ifp; - rt->rt_rmx.rmx_pksent++; + counter_u64_add(rt->rt_pksent, 1); if (rt->rt_flags & RTF_GATEWAY) bcopy(satosin(rt->rt_gateway), &dst, sizeof(dst)); diff --git a/sys/nfs/bootp_subr.c b/sys/nfs/bootp_subr.c index 7b84f94..55bc165 100644 --- a/sys/nfs/bootp_subr.c +++ b/sys/nfs/bootp_subr.c @@ -342,7 +342,7 @@ bootpboot_p_rtentry(struct rtentry *rt) bootpboot_p_sa(rt->rt_gateway, NULL); printf(" "); printf("flags %x", (unsigned short) rt->rt_flags); - printf(" %d", (int) rt->rt_rmx.rmx_expire); + printf(" %d", (int) rt->rt_expire); printf(" %s\n", rt->rt_ifp->if_xname); } diff --git a/usr.bin/netstat/main.c b/usr.bin/netstat/main.c index dbec760..89a7f57 100644 --- a/usr.bin/netstat/main.c +++ b/usr.bin/netstat/main.c @@ -749,6 +749,19 @@ kread(u_long addr, void *buf, size_t size) } /* + * Read single counter(9). + */ +uint64_t +kread_counter(u_long addr) +{ + + if (kvmd_init() < 0) + return (-1); + + return (kvm_counter_u64_fetch(kvmd, addr)); +} + +/* * Read an array of N counters in kernel memory into array of N uint64_t's. */ int diff --git a/usr.bin/netstat/netstat.h b/usr.bin/netstat/netstat.h index fd4ec96..414b4ce 100644 --- a/usr.bin/netstat/netstat.h +++ b/usr.bin/netstat/netstat.h @@ -60,6 +60,7 @@ extern int live; /* true if we are examining a live system */ struct nlist; int kread(u_long addr, void *buf, size_t size); +uint64_t kread_counter(u_long addr); int kread_counters(u_long addr, void *buf, size_t size); int kresolve_list(struct nlist *); const char *plural(uintmax_t); diff --git a/usr.bin/netstat/route.c b/usr.bin/netstat/route.c index 75c255f..eee5ff7 100644 --- a/usr.bin/netstat/route.c +++ b/usr.bin/netstat/route.c @@ -48,6 +48,7 @@ __FBSDID("$FreeBSD$"); #include <net/if_dl.h> #include <net/if_types.h> #include <net/radix.h> +#define _WANT_RTENTRY #include <net/route.h> #include <netinet/in.h> @@ -181,7 +182,7 @@ routepr(int fibnum, int af) /* * Since kernel & userland use different timebase * (time_uptime vs time_second) and we are reading kernel memory - * directly we should do rt_rmx.rmx_expire --> expire_time conversion. + * directly we should do rt_expire --> expire_time conversion. */ if (clock_gettime(CLOCK_UPTIME, &uptime) < 0) err(EX_OSERR, "clock_gettime() failed"); @@ -256,8 +257,7 @@ pr_family(int af1) static int wid_dst; static int wid_gw; static int wid_flags; -static int wid_refs; -static int wid_use; +static int wid_pksent; static int wid_mtu; static int wid_if; static int wid_expire; @@ -268,8 +268,7 @@ size_cols(int ef, struct radix_node *rn) wid_dst = WID_DST_DEFAULT(ef); wid_gw = WID_GW_DEFAULT(ef); wid_flags = 6; - wid_refs = 6; - wid_use = 8; + wid_pksent = 8; wid_mtu = 6; wid_if = WID_IF_DEFAULT(ef); wid_expire = 6; @@ -329,16 +328,10 @@ size_cols_rtentry(struct rtentry *rt) len = strlen(bp); wid_flags = MAX(len, wid_flags); - if (addr.u_sa.sa_family == AF_INET || Wflag) { - len = snprintf(buffer, sizeof(buffer), "%d", rt->rt_refcnt); - wid_refs = MAX(len, wid_refs); - len = snprintf(buffer, sizeof(buffer), "%lu", rt->rt_use); - wid_use = MAX(len, wid_use); - if (Wflag && rt->rt_rmx.rmx_mtu != 0) { - len = snprintf(buffer, sizeof(buffer), - "%lu", rt->rt_rmx.rmx_mtu); - wid_mtu = MAX(len, wid_mtu); - } + if (Wflag) { + len = snprintf(buffer, sizeof(buffer), "%lu", + kread_counter((u_long )rt->rt_pksent)); + wid_pksent = MAX(len, wid_pksent); } if (rt->rt_ifp) { if (rt->rt_ifp != lastif) { @@ -349,11 +342,11 @@ size_cols_rtentry(struct rtentry *rt) lastif = rt->rt_ifp; wid_if = MAX(len, wid_if); } - if (rt->rt_rmx.rmx_expire) { + if (rt->rt_expire) { time_t expire_time; if ((expire_time = - rt->rt_rmx.rmx_expire - uptime.tv_sec) > 0) { + rt->rt_expire - uptime.tv_sec) > 0) { len = snprintf(buffer, sizeof(buffer), "%d", (int)expire_time); wid_expire = MAX(len, wid_expire); @@ -373,10 +366,11 @@ pr_rthdr(int af1) if (Aflag) printf("%-8.8s ","Address"); if (Wflag) { - printf("%-*.*s %-*.*s %-*.*s %*.*s %*.*s %*s\n", + printf("%-*.*s %-*.*s %-*.*s %*.*s %*.*s %*.*s %*s\n", wid_dst, wid_dst, "Destination", wid_gw, wid_gw, "Gateway", wid_flags, wid_flags, "Flags", + wid_pksent, wid_pksent, "Use", wid_mtu, wid_mtu, "Mtu", wid_if, wid_if, "Netif", wid_expire, "Expire"); @@ -661,6 +655,8 @@ p_rtentry_sysctl(struct rt_msghdr *rtm) snprintf(buffer, sizeof(buffer), "%%-%d.%ds ", wid_flags, wid_flags); p_flags(rtm->rtm_flags, buffer); if (Wflag) { + printf("%*lu ", wid_pksent, rtm->rtm_rmx.rmx_pksent); + if (rtm->rtm_rmx.rmx_mtu != 0) printf("%*lu ", wid_mtu, rtm->rtm_rmx.rmx_mtu); else @@ -870,17 +866,14 @@ p_rtentry_kvm(struct rtentry *rt) p_sockaddr(kgetsa(rt->rt_gateway), NULL, RTF_HOST, wid_gw); snprintf(buffer, sizeof(buffer), "%%-%d.%ds ", wid_flags, wid_flags); p_flags(rt->rt_flags, buffer); - if (addr.u_sa.sa_family == AF_INET || Wflag) { -#if 0 - printf("%*d %*lu ", wid_refs, rt->rt_refcnt, - wid_use, rt->rt_use); -#endif - if (Wflag) { - if (rt->rt_rmx.rmx_mtu != 0) - printf("%*lu ", wid_mtu, rt->rt_rmx.rmx_mtu); - else - printf("%*s ", wid_mtu, ""); - } + if (Wflag) { + printf("%*lu ", wid_pksent, + kread_counter((u_long )rt->rt_pksent)); + + if (rt->rt_mtu != 0) + printf("%*lu ", wid_mtu, rt->rt_mtu); + else + printf("%*s ", wid_mtu, ""); } if (rt->rt_ifp) { if (rt->rt_ifp != lastif) { @@ -892,11 +885,11 @@ p_rtentry_kvm(struct rtentry *rt) lastif = rt->rt_ifp; } printf("%*.*s", wid_if, wid_if, prettyname); - if (rt->rt_rmx.rmx_expire) { + if (rt->rt_expire) { time_t expire_time; if ((expire_time = - rt->rt_rmx.rmx_expire - uptime.tv_sec) > 0) + rt->rt_expire - uptime.tv_sec) > 0) printf(" %*d", wid_expire, (int)expire_time); } if (rt->rt_nodes[0].rn_dupedkey) |