summaryrefslogtreecommitdiff
path: root/sys/net
diff options
context:
space:
mode:
authorMartin Pieuchot <mpi@cvs.openbsd.org>2015-02-11 23:34:44 +0000
committerMartin Pieuchot <mpi@cvs.openbsd.org>2015-02-11 23:34:44 +0000
commitd498aba64e76cf8a05994cdbeabb95aa177eb2bc (patch)
tree05935e08add6b2705c4f060a3ef55ef8d3be2beb /sys/net
parent2d34bd4a668fcf2e31b2cf126e20e282c437033e (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.c58
-rw-r--r--sys/net/route.h5
-rw-r--r--sys/net/rtsock.c6
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;