summaryrefslogtreecommitdiff
path: root/sys/net
diff options
context:
space:
mode:
authorMartin Pieuchot <mpi@cvs.openbsd.org>2016-06-14 09:44:42 +0000
committerMartin Pieuchot <mpi@cvs.openbsd.org>2016-06-14 09:44:42 +0000
commit8590c53b6d471542cc30298ac39ac7361157ab52 (patch)
treefd11877216d27f956d4db30ce654c1f7b880a6d8 /sys/net
parentef7dbacaa471766ec40e170a49d20a27f360197f (diff)
Store the source address associated with a route in its own chunk of
memory. This will allow to unlink 'sruct rtentry' and 'struct ifaddr' to be able to add route entries without needing an address. ok sthen@, visa@, florian@
Diffstat (limited to 'sys/net')
-rw-r--r--sys/net/route.c43
-rw-r--r--sys/net/route.h3
-rw-r--r--sys/net/rtsock.c6
3 files changed, 36 insertions, 16 deletions
diff --git a/sys/net/route.c b/sys/net/route.c
index ac6b9cfb4cd..50cd1112ae3 100644
--- a/sys/net/route.c
+++ b/sys/net/route.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: route.c,v 1.307 2016/06/08 13:26:06 mpi Exp $ */
+/* $OpenBSD: route.c,v 1.308 2016/06/14 09:44:41 mpi Exp $ */
/* $NetBSD: route.c,v 1.14 1996/02/13 22:00:46 christos Exp $ */
/*
@@ -139,6 +139,8 @@
#include <net/if_enc.h>
#endif
+#define ROUNDUP(a) (a>0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
+
/* Give some jitter to hash, to avoid synchronization between routers. */
static uint32_t rt_hashjitter;
@@ -151,6 +153,7 @@ struct pool rtentry_pool; /* pool for rtentry structures */
struct pool rttimer_pool; /* pool for rttimer structures */
void rt_timer_init(void);
+int rt_setaddr(struct rtentry *, struct sockaddr *);
int rtflushclone1(struct rtentry *, void *, u_int);
void rtflushclone(unsigned int, struct rtentry *);
int rt_if_remove_rtdelete(struct rtentry *, void *, u_int);
@@ -434,7 +437,6 @@ rtref(struct rtentry *rt)
void
rtfree(struct rtentry *rt)
{
- struct ifaddr *ifa;
int refcnt;
if (rt == NULL)
@@ -452,16 +454,14 @@ rtfree(struct rtentry *rt)
KERNEL_LOCK();
rt_timer_remove_all(rt);
- ifa = rt->rt_ifa;
- if (ifa)
- ifafree(ifa);
+ ifafree(rt->rt_ifa);
rtlabel_unref(rt->rt_labelid);
#ifdef MPLS
if (rt->rt_flags & RTF_MPLS)
free(rt->rt_llinfo, M_TEMP, sizeof(struct rt_mpls));
#endif
- if (rt->rt_gateway)
- free(rt->rt_gateway, M_RTABLE, 0);
+ free(rt->rt_addr, M_RTABLE, ROUNDUP(rt->rt_addr->sa_len));
+ free(rt->rt_gateway, M_RTABLE, ROUNDUP(rt->rt_gateway->sa_len));
free(rt_key(rt), M_RTABLE, rt_key(rt)->sa_len);
KERNEL_UNLOCK();
@@ -486,7 +486,7 @@ rt_sendmsg(struct rtentry *rt, int cmd, u_int rtableid)
ifp = if_get(rt->rt_ifidx);
if (ifp != NULL) {
info.rti_info[RTAX_IFP] = sdltosa(ifp->if_sadl);
- info.rti_info[RTAX_IFA] = rt->rt_ifa->ifa_addr;
+ info.rti_info[RTAX_IFA] = rt->rt_addr;
}
rt_missmsg(cmd, &info, rt->rt_flags, rt->rt_priority, rt->rt_ifidx, 0,
@@ -767,8 +767,6 @@ ifa_ifwithroute(int flags, struct sockaddr *dst, struct sockaddr *gateway,
return (ifa);
}
-#define ROUNDUP(a) (a>0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
-
int
rt_getifa(struct rt_addrinfo *info, u_int rtid)
{
@@ -958,7 +956,7 @@ rtrequest(int req, struct rt_addrinfo *info, u_int8_t prio,
* will get the new address and interface later.
*/
info->rti_ifa = NULL;
- info->rti_info[RTAX_IFA] = rt->rt_ifa->ifa_addr;
+ info->rti_info[RTAX_IFA] = rt->rt_addr;
}
info->rti_flags = rt->rt_flags | (RTF_CLONED|RTF_HOST);
@@ -1090,10 +1088,12 @@ rtrequest(int req, struct rt_addrinfo *info, u_int8_t prio,
* the routing table because the radix MPATH code use
* it to (re)order routes.
*/
- if ((error = rt_setgate(rt, info->rti_info[RTAX_GATEWAY]))) {
+ if ((error = rt_setaddr(rt, ifa->ifa_addr)) ||
+ (error = rt_setgate(rt, info->rti_info[RTAX_GATEWAY]))) {
ifafree(ifa);
rtfree(rt->rt_parent);
rtfree(rt->rt_gwroute);
+ free(rt->rt_addr, M_RTABLE, 0);
free(rt->rt_gateway, M_RTABLE, 0);
free(ndst, M_RTABLE, dlen);
pool_put(&rtentry_pool, rt);
@@ -1124,6 +1124,7 @@ rtrequest(int req, struct rt_addrinfo *info, u_int8_t prio,
ifafree(ifa);
rtfree(rt->rt_parent);
rtfree(rt->rt_gwroute);
+ free(rt->rt_addr, M_RTABLE, 0);
free(rt->rt_gateway, M_RTABLE, 0);
free(ndst, M_RTABLE, dlen);
pool_put(&rtentry_pool, rt);
@@ -1150,6 +1151,24 @@ rtrequest(int req, struct rt_addrinfo *info, u_int8_t prio,
}
int
+rt_setaddr(struct rtentry *rt, struct sockaddr *addr)
+{
+ int alen = ROUNDUP(addr->sa_len);
+ struct sockaddr *sa;
+
+ KASSERT(rt->rt_addr == NULL);
+
+ sa = malloc(alen, M_RTABLE, M_NOWAIT);
+ if (sa == NULL)
+ return (ENOBUFS);
+
+ memmove(sa, addr, alen);
+ rt->rt_addr = sa;
+
+ return (0);
+}
+
+int
rt_setgate(struct rtentry *rt, struct sockaddr *gate)
{
int glen = ROUNDUP(gate->sa_len);
diff --git a/sys/net/route.h b/sys/net/route.h
index 940d473577f..3286f4118bb 100644
--- a/sys/net/route.h
+++ b/sys/net/route.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: route.h,v 1.136 2016/06/03 02:56:59 dlg Exp $ */
+/* $OpenBSD: route.h,v 1.137 2016/06/14 09:44:41 mpi Exp $ */
/* $NetBSD: route.h,v 1.9 1996/02/13 22:00:49 christos Exp $ */
/*
@@ -99,6 +99,7 @@ struct rtentry {
struct sockaddr *rt_dest; /* destination */
SRPL_ENTRY(rtentry) rt_next; /* Next multipath entry to our dst. */
#endif
+ struct sockaddr *rt_addr; /* the answer: address to use */
struct sockaddr *rt_gateway; /* value */
struct ifaddr *rt_ifa; /* the answer: interface addr to use */
caddr_t rt_llinfo; /* pointer to link level info cache or
diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c
index f3018d85cf6..4523c771ce9 100644
--- a/sys/net/rtsock.c
+++ b/sys/net/rtsock.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rtsock.c,v 1.190 2016/06/03 02:56:59 dlg Exp $ */
+/* $OpenBSD: rtsock.c,v 1.191 2016/06/14 09:44:41 mpi Exp $ */
/* $NetBSD: rtsock.c,v 1.18 1996/03/29 00:32:10 cgd Exp $ */
/*
@@ -695,7 +695,7 @@ report:
ifp = if_get(rt->rt_ifidx);
if (ifp != NULL && rtm->rtm_addrs & (RTA_IFP|RTA_IFA)) {
info.rti_info[RTAX_IFP] = sdltosa(ifp->if_sadl);
- info.rti_info[RTAX_IFA] = rt->rt_ifa->ifa_addr;
+ info.rti_info[RTAX_IFA] = rt->rt_addr;
if (ifp->if_flags & IFF_POINTOPOINT)
info.rti_info[RTAX_BRD] =
rt->rt_ifa->ifa_dstaddr;
@@ -1279,7 +1279,7 @@ sysctl_dumpentry(struct rtentry *rt, void *v, unsigned int id)
ifp = if_get(rt->rt_ifidx);
if (ifp != NULL) {
info.rti_info[RTAX_IFP] = sdltosa(ifp->if_sadl);
- info.rti_info[RTAX_IFA] = rt->rt_ifa->ifa_addr;
+ info.rti_info[RTAX_IFA] = rt->rt_addr;
if (ifp->if_flags & IFF_POINTOPOINT)
info.rti_info[RTAX_BRD] = rt->rt_ifa->ifa_dstaddr;
}