diff options
author | Martin Pieuchot <mpi@cvs.openbsd.org> | 2015-02-11 23:34:44 +0000 |
---|---|---|
committer | Martin Pieuchot <mpi@cvs.openbsd.org> | 2015-02-11 23:34:44 +0000 |
commit | d498aba64e76cf8a05994cdbeabb95aa177eb2bc (patch) | |
tree | 05935e08add6b2705c4f060a3ef55ef8d3be2beb /sys/net | |
parent | 2d34bd4a668fcf2e31b2cf126e20e282c437033e (diff) |
Do not store the key and the gateway of a route entry in the same chunk
of memory.
The key (destination) is only set once, when the route is inserted in
the routing table, and does not need to change afterward. The gateway
might change and rt_setgate() will do all the checks for you.
ok claudio@
Diffstat (limited to 'sys/net')
-rw-r--r-- | sys/net/route.c | 58 | ||||
-rw-r--r-- | sys/net/route.h | 5 | ||||
-rw-r--r-- | sys/net/rtsock.c | 6 |
3 files changed, 37 insertions, 32 deletions
diff --git a/sys/net/route.c b/sys/net/route.c index cd0d51a095f..c3959f26ccf 100644 --- a/sys/net/route.c +++ b/sys/net/route.c @@ -1,4 +1,4 @@ -/* $OpenBSD: route.c,v 1.205 2015/02/10 03:04:11 claudio Exp $ */ +/* $OpenBSD: route.c,v 1.206 2015/02/11 23:34:43 mpi Exp $ */ /* $NetBSD: route.c,v 1.14 1996/02/13 22:00:46 christos Exp $ */ /* @@ -373,6 +373,8 @@ rtfree(struct rtentry *rt) if (rt->rt_flags & RTF_MPLS) free(rt->rt_llinfo, M_TEMP, 0); #endif + if (rt->rt_gateway) + free(rt->rt_gateway, M_RTABLE, 0); free(rt_key(rt), M_RTABLE, 0); pool_put(&rtentry_pool, rt); } @@ -495,7 +497,7 @@ create: rt->rt_flags |= RTF_MODIFIED; flags |= RTF_MODIFIED; stat = &rtstat.rts_newgateway; - rt_setgate(rt, rt_key(rt), gateway, rdomain); + rt_setgate(rt, gateway, rdomain); } } else error = EHOSTUNREACH; @@ -716,7 +718,7 @@ rtrequest1(int req, struct rt_addrinfo *info, u_int8_t prio, struct ifaddr *ifa; struct sockaddr *ndst; struct sockaddr_rtlabel *sa_rl, sa_rl2; - int error; + int dlen, error; #ifdef MPLS struct sockaddr_mpls *sa_mpls; #endif @@ -843,22 +845,30 @@ rtrequest1(int req, struct rt_addrinfo *info, u_int8_t prio, if (rt == NULL) return (ENOBUFS); + dlen = info->rti_info[RTAX_DST]->sa_len; + ndst = malloc(dlen, M_RTABLE, M_NOWAIT); + if (ndst == NULL) { + pool_put(&rtentry_pool, rt); + return (ENOBUFS); + } + rt->rt_flags = info->rti_flags; rt->rt_tableid = tableid; rt->rt_priority = prio; /* init routing priority */ LIST_INIT(&rt->rt_timer); - if ((error = rt_setgate(rt, info->rti_info[RTAX_DST], - info->rti_info[RTAX_GATEWAY], tableid))) { + rt->rt_nodes->rn_key = (caddr_t)ndst; + memcpy(ndst, info->rti_info[RTAX_DST], dlen); + + if ((error = rt_setgate(rt, info->rti_info[RTAX_GATEWAY], + tableid))) { pool_put(&rtentry_pool, rt); return (error); } - ndst = rt_key(rt); - if (info->rti_info[RTAX_NETMASK] != NULL) { + + if (info->rti_info[RTAX_NETMASK] != NULL) rt_maskedcopy(info->rti_info[RTAX_DST], ndst, info->rti_info[RTAX_NETMASK]); - } else - memcpy(ndst, info->rti_info[RTAX_DST], - info->rti_info[RTAX_DST]->sa_len); + #ifndef SMALL_KERNEL if (rn_mpath_capable(rnh)) { /* check the link state since the table supports it */ @@ -894,6 +904,8 @@ rtrequest1(int req, struct rt_addrinfo *info, u_int8_t prio, if (rt->rt_llinfo == NULL) { if (rt->rt_gwroute) rtfree(rt->rt_gwroute); + if (rt->rt_gateway) + free(rt->rt_gateway, M_RTABLE, 0); free(rt_key(rt), M_RTABLE, 0); pool_put(&rtentry_pool, rt); return (ENOMEM); @@ -964,6 +976,8 @@ rtrequest1(int req, struct rt_addrinfo *info, u_int8_t prio, rtfree(rt->rt_parent); if (rt->rt_gwroute) rtfree(rt->rt_gwroute); + if (rt->rt_gateway) + free(rt->rt_gateway, M_RTABLE, 0); free(rt_key(rt), M_RTABLE, 0); pool_put(&rtentry_pool, rt); return (EEXIST); @@ -989,28 +1003,20 @@ rtrequest1(int req, struct rt_addrinfo *info, u_int8_t prio, } int -rt_setgate(struct rtentry *rt, struct sockaddr *dst, struct sockaddr *gate, - u_int tableid) +rt_setgate(struct rtentry *rt, struct sockaddr *gate, unsigned int tableid) { - caddr_t new, old; - int dlen = ROUNDUP(dst->sa_len), glen = ROUNDUP(gate->sa_len); + int glen = ROUNDUP(gate->sa_len); + struct sockaddr *sa; if (rt->rt_gateway == NULL || glen > ROUNDUP(rt->rt_gateway->sa_len)) { - old = (caddr_t)rt_key(rt); - new = malloc(dlen + glen, M_RTABLE, M_NOWAIT); - if (new == NULL) + sa = malloc(glen, M_RTABLE, M_NOWAIT); + if (sa == NULL) return (ENOBUFS); - rt->rt_nodes->rn_key = new; - } else { - new = rt->rt_nodes->rn_key; - old = NULL; + free(rt->rt_gateway, M_RTABLE, 0); + rt->rt_gateway = sa; } - rt->rt_gateway = (struct sockaddr *)(new + dlen); memmove(rt->rt_gateway, gate, glen); - if (old) { - memmove(new, dst, dlen); - free(old, M_RTABLE, 0); - } + if (rt->rt_gwroute != NULL) { rtfree(rt->rt_gwroute); rt->rt_gwroute = NULL; diff --git a/sys/net/route.h b/sys/net/route.h index 74a0d5da23e..91637f91676 100644 --- a/sys/net/route.h +++ b/sys/net/route.h @@ -1,4 +1,4 @@ -/* $OpenBSD: route.h,v 1.104 2015/01/13 12:14:00 mpi Exp $ */ +/* $OpenBSD: route.h,v 1.105 2015/02/11 23:34:43 mpi Exp $ */ /* $NetBSD: route.h,v 1.9 1996/02/13 22:00:49 christos Exp $ */ /* @@ -360,8 +360,7 @@ void rt_sendmsg(struct rtentry *, int, u_int); void rt_sendaddrmsg(struct rtentry *, int); void rt_missmsg(int, struct rt_addrinfo *, int, struct ifnet *, int, u_int); -int rt_setgate(struct rtentry *, struct sockaddr *, - struct sockaddr *, u_int); +int rt_setgate(struct rtentry *, struct sockaddr *, unsigned int); int rt_checkgate(struct ifnet *, struct rtentry *, struct sockaddr *, unsigned int, struct rtentry **); void rt_setmetrics(u_long, struct rt_metrics *, struct rt_kmetrics *); diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c index 2c4802e1068..b4ff9fccf1f 100644 --- a/sys/net/rtsock.c +++ b/sys/net/rtsock.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rtsock.c,v 1.156 2015/01/13 12:14:00 mpi Exp $ */ +/* $OpenBSD: rtsock.c,v 1.157 2015/02/11 23:34:43 mpi Exp $ */ /* $NetBSD: rtsock.c,v 1.18 1996/03/29 00:32:10 cgd Exp $ */ /* @@ -750,8 +750,8 @@ report: newgate = 1; } if (info.rti_info[RTAX_GATEWAY] != NULL && - (error = rt_setgate(rt, rt_key(rt), - info.rti_info[RTAX_GATEWAY], tableid))) + (error = rt_setgate(rt, info.rti_info[RTAX_GATEWAY], + tableid))) goto flush; /* * new gateway could require new ifaddr, ifp; |