Index: head/sys/net/route.h =================================================================== --- head/sys/net/route.h +++ head/sys/net/route.h @@ -378,7 +378,6 @@ int rt_routemsg(int, struct rtentry *, struct ifnet *ifp, int, int); int rt_routemsg_info(int, struct rt_addrinfo *, int); void rt_newmaddrmsg(int, struct ifmultiaddr *); -int rt_setgate(struct rtentry *, struct sockaddr *, struct sockaddr *); void rt_maskedcopy(struct sockaddr *, struct sockaddr *, struct sockaddr *); struct rib_head *rt_table_init(int, int, u_int); void rt_table_destroy(struct rib_head *); Index: head/sys/net/route.c =================================================================== --- head/sys/net/route.c +++ head/sys/net/route.c @@ -241,10 +241,6 @@ { struct rtentry *rt = mem; - rt->rt_pksent = counter_u64_alloc(how); - if (rt->rt_pksent == NULL) - return (ENOMEM); - RT_LOCK_INIT(rt); return (0); @@ -256,7 +252,6 @@ struct rtentry *rt = mem; RT_LOCK_DESTROY(rt); - counter_u64_free(rt->rt_pksent); } static int @@ -265,7 +260,6 @@ struct rtentry *rt = mem; bzero(rt, offsetof(struct rtentry, rt_endzero)); - counter_u64_zero(rt->rt_pksent); rt->rt_chain = NULL; return (0); @@ -551,12 +545,6 @@ goto done; } #endif - /* - * The key is separatly alloc'd so free it (see rt_setgate()). - * This also frees the gateway, as they are always malloc'd - * together. - */ - R_Free(rt_key(rt)); /* Unreference nexthop */ nhop_free(rt->rt_nhop); @@ -1557,6 +1545,9 @@ (gateway->sa_family != AF_UNSPEC) && (gateway->sa_family != AF_LINK)) return (EINVAL); + if (dst->sa_len > sizeof(((struct rtentry *)NULL)->rt_dstb)) + return (EINVAL); + if (info->rti_ifa == NULL) { error = rt_getifa_fib(info, rnh->rib_fibnum); if (error) @@ -1582,16 +1573,11 @@ rt->rt_flags = RTF_UP | flags; rt->rt_fibnum = rnh->rib_fibnum; rt->rt_nhop = nh; - /* - * Add the gateway. Possibly re-malloc-ing the storage for it. - */ - if ((error = rt_setgate(rt, dst, gateway)) != 0) { - ifa_free(info->rti_ifa); - nhop_free(nh); - uma_zfree(V_rtzone, rt); - return (error); - } + /* Fill in dst */ + memcpy(&rt->rt_dst, dst, dst->sa_len); + rt_key(rt) = &rt->rt_dst; + /* * point to the (possibly newly malloc'd) dest address. */ @@ -1623,7 +1609,6 @@ rt_mpath_conflict(rnh, rt, netmask)) { RIB_WUNLOCK(rnh); - R_Free(rt_key(rt)); nhop_free(nh); uma_zfree(V_rtzone, rt); return (EEXIST); @@ -1663,7 +1648,6 @@ * then un-make it (this should be a function) */ if (rn == NULL) { - R_Free(rt_key(rt)); nhop_free(nh); uma_zfree(V_rtzone, rt); return (EEXIST); @@ -1897,40 +1881,6 @@ if (info->rti_mflags & RTV_EXPIRE) rt->rt_expire = info->rti_rmx->rmx_expire ? info->rti_rmx->rmx_expire - time_second + time_uptime : 0; -} - -int -rt_setgate(struct rtentry *rt, struct sockaddr *dst, struct sockaddr *gate) -{ - /* XXX dst may be overwritten, can we move this to below */ - int dlen = SA_SIZE(dst), glen = SA_SIZE(gate); - - /* - * Prepare to store the gateway in rt->rt_gateway. - * Both dst and gateway are stored one after the other in the same - * malloc'd chunk. If we have room, we can reuse the old buffer, - * rt_gateway already points to the right place. - * Otherwise, malloc a new block and update the 'dst' address. - */ - if (rt_key(rt) == NULL) { - caddr_t new; - - R_Malloc(new, caddr_t, dlen + glen); - if (new == NULL) - return ENOBUFS; - /* - * XXX note, we copy from *dst and not *rt_key(rt) because - * rt_setgate() can be called to initialize a newly - * allocated route entry, in which case rt_key(rt) == NULL - * (and also rt->rt_gateway == NULL). - * Free()/free() handle a NULL argument just fine. - */ - bcopy(dst, new, dlen); - R_Free(rt_key(rt)); /* free old block, if any */ - rt_key(rt) = (struct sockaddr *)new; - } - - return (0); } void Index: head/sys/net/route/route_ddb.c =================================================================== --- head/sys/net/route/route_ddb.c +++ head/sys/net/route/route_ddb.c @@ -48,11 +48,9 @@ #include #include #include -#include #include -#include #include -#include +#include /* * Unfortunately, RTF_ values are expressed as raw masks rather than powers of Index: head/sys/net/route/route_var.h =================================================================== --- head/sys/net/route/route_var.h +++ head/sys/net/route/route_var.h @@ -35,6 +35,7 @@ #ifndef RNF_NORMAL #include #endif +#include /* struct sockaddr_in */ #include struct nh_control; @@ -120,14 +121,33 @@ #define rt_mask(r) (*((struct sockaddr **)(&(r)->rt_nodes->rn_mask))) #define rt_key_const(r) (*((const struct sockaddr * const *)(&(r)->rt_nodes->rn_key))) #define rt_mask_const(r) (*((const struct sockaddr * const *)(&(r)->rt_nodes->rn_mask))) + + /* + * 2 radix_node structurs above consists of 2x6 pointers, leaving + * 4 pointers (32 bytes) of the second cache line on amd64. + * + */ struct nhop_object *rt_nhop; /* nexthop data */ + union { + /* + * Destination address storage. + * sizeof(struct sockaddr_in6) == 28, however + * the dataplane-relevant part (e.g. address) lies + * at offset 8..24, making the address not crossing + * cacheline boundary. + */ + struct sockaddr_in rt_dst4; + struct sockaddr_in6 rt_dst6; + struct sockaddr rt_dst; + char rt_dstb[28]; + }; + int rt_flags; /* up/down?, host/net */ int rt_refcnt; /* # held references */ u_int rt_fibnum; /* which FIB */ 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 */ +#define rt_endzero rt_mtx struct mtx rt_mtx; /* mutex for routing entry */ struct rtentry *rt_chain; /* pointer to next rtentry to delete */ }; Index: head/sys/net/rtsock.c =================================================================== --- head/sys/net/rtsock.c +++ head/sys/net/rtsock.c @@ -1078,7 +1078,6 @@ bzero(out, sizeof(*out)); out->rmx_mtu = rt->rt_nhop->nh_mtu; out->rmx_weight = rt->rt_weight; - out->rmx_pksent = counter_u64_fetch(rt->rt_pksent); out->rmx_nhidx = nhop_get_idx(rt->rt_nhop); /* Kernel -> userland timebase conversion. */ out->rmx_expire = rt->rt_expire ?