summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/net/route.c128
-rw-r--r--sys/net/route.h3
-rw-r--r--sys/net/rtsock.c125
3 files changed, 127 insertions, 129 deletions
diff --git a/sys/net/route.c b/sys/net/route.c
index 45ec6e23b8d..f172223e81c 100644
--- a/sys/net/route.c
+++ b/sys/net/route.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: route.c,v 1.359 2017/06/09 12:56:43 mpi Exp $ */
+/* $OpenBSD: route.c,v 1.360 2017/07/24 09:20:32 mpi Exp $ */
/* $NetBSD: route.c,v 1.14 1996/02/13 22:00:46 christos Exp $ */
/*
@@ -134,11 +134,6 @@
#include <netmpls/mpls.h>
#endif
-#ifdef IPSEC
-#include <netinet/ip_ipsp.h>
-#include <net/if_enc.h>
-#endif
-
#ifdef BFD
#include <net/bfd.h>
#endif
@@ -166,9 +161,6 @@ int rt_ifa_purge_walker(struct rtentry *, void *, unsigned int);
struct rtentry *rt_match(struct sockaddr *, uint32_t *, int, unsigned int);
struct sockaddr *rt_plentosa(sa_family_t, int, struct sockaddr_in6 *);
-struct ifaddr *ifa_ifwithroute(int, struct sockaddr *, struct sockaddr *,
- u_int);
-
#ifdef DDB
void db_print_sa(struct sockaddr *);
void db_print_ifa(struct ifaddr *);
@@ -714,120 +706,6 @@ rtflushclone(unsigned int rtableid, struct rtentry *parent)
rtable_walk(rtableid, rt_key(parent)->sa_family, rtflushclone1, parent);
}
-struct ifaddr *
-ifa_ifwithroute(int flags, struct sockaddr *dst, struct sockaddr *gateway,
- u_int rtableid)
-{
- struct ifaddr *ifa;
-
- if ((flags & RTF_GATEWAY) == 0) {
- /*
- * If we are adding a route to an interface,
- * and the interface is a pt to pt link
- * we should search for the destination
- * as our clue to the interface. Otherwise
- * we can use the local address.
- */
- ifa = NULL;
- if (flags & RTF_HOST)
- ifa = ifa_ifwithdstaddr(dst, rtableid);
- if (ifa == NULL)
- ifa = ifa_ifwithaddr(gateway, rtableid);
- } else {
- /*
- * If we are adding a route to a remote net
- * or host, the gateway may still be on the
- * other end of a pt to pt link.
- */
- ifa = ifa_ifwithdstaddr(gateway, rtableid);
- }
- if (ifa == NULL) {
- if (gateway->sa_family == AF_LINK) {
- struct sockaddr_dl *sdl = satosdl(gateway);
- struct ifnet *ifp = if_get(sdl->sdl_index);
-
- if (ifp != NULL)
- ifa = ifaof_ifpforaddr(dst, ifp);
- if_put(ifp);
- } else {
- struct rtentry *rt;
-
- rt = rtalloc(gateway, RT_RESOLVE, rtable_l2(rtableid));
- if (rt != NULL)
- ifa = rt->rt_ifa;
- rtfree(rt);
- }
- }
- if (ifa == NULL)
- return (NULL);
- if (ifa->ifa_addr->sa_family != dst->sa_family) {
- struct ifaddr *oifa = ifa;
- ifa = ifaof_ifpforaddr(dst, ifa->ifa_ifp);
- if (ifa == NULL)
- ifa = oifa;
- }
- return (ifa);
-}
-
-int
-rt_getifa(struct rt_addrinfo *info, u_int rtid)
-{
- struct ifnet *ifp = NULL;
-
- /*
- * ifp may be specified by sockaddr_dl when protocol address
- * is ambiguous
- */
- if (info->rti_info[RTAX_IFP] != NULL) {
- struct sockaddr_dl *sdl;
-
- sdl = satosdl(info->rti_info[RTAX_IFP]);
- ifp = if_get(sdl->sdl_index);
- }
-
-#ifdef IPSEC
- /*
- * If the destination is a PF_KEY address, we'll look
- * for the existence of a encap interface number or address
- * in the options list of the gateway. By default, we'll return
- * enc0.
- */
- if (info->rti_info[RTAX_DST] &&
- info->rti_info[RTAX_DST]->sa_family == PF_KEY)
- info->rti_ifa = enc_getifa(rtid, 0);
-#endif
-
- if (info->rti_ifa == NULL && info->rti_info[RTAX_IFA] != NULL)
- info->rti_ifa = ifa_ifwithaddr(info->rti_info[RTAX_IFA], rtid);
-
- if (info->rti_ifa == NULL) {
- struct sockaddr *sa;
-
- if ((sa = info->rti_info[RTAX_IFA]) == NULL)
- if ((sa = info->rti_info[RTAX_GATEWAY]) == NULL)
- sa = info->rti_info[RTAX_DST];
-
- if (sa != NULL && ifp != NULL)
- info->rti_ifa = ifaof_ifpforaddr(sa, ifp);
- else if (info->rti_info[RTAX_DST] != NULL &&
- info->rti_info[RTAX_GATEWAY] != NULL)
- info->rti_ifa = ifa_ifwithroute(info->rti_flags,
- info->rti_info[RTAX_DST],
- info->rti_info[RTAX_GATEWAY],
- rtid);
- else if (sa != NULL)
- info->rti_ifa = ifa_ifwithroute(info->rti_flags,
- sa, sa, rtid);
- }
-
- if_put(ifp);
-
- if (info->rti_ifa == NULL)
- return (ENETUNREACH);
-
- return (0);
-}
-
int
rtrequest_delete(struct rt_addrinfo *info, u_int8_t prio, struct ifnet *ifp,
struct rtentry **ret_nrt, u_int tableid)
@@ -939,8 +817,8 @@ rtrequest(int req, struct rt_addrinfo *info, u_int8_t prio,
/* FALLTHROUGH */
case RTM_ADD:
- if (info->rti_ifa == NULL && (error = rt_getifa(info, tableid)))
- return (error);
+ if (info->rti_ifa == NULL)
+ return (EINVAL);
ifa = info->rti_ifa;
ifp = ifa->ifa_ifp;
if (prio == 0)
diff --git a/sys/net/route.h b/sys/net/route.h
index 1e73d2d1dfb..c7236855315 100644
--- a/sys/net/route.h
+++ b/sys/net/route.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: route.h,v 1.162 2017/06/09 12:56:43 mpi Exp $ */
+/* $OpenBSD: route.h,v 1.163 2017/07/24 09:20:32 mpi Exp $ */
/* $NetBSD: route.h,v 1.9 1996/02/13 22:00:49 christos Exp $ */
/*
@@ -450,7 +450,6 @@ struct rtentry *rtalloc(struct sockaddr *, int, unsigned int);
void rtref(struct rtentry *);
void rtfree(struct rtentry *);
-int rt_getifa(struct rt_addrinfo *, u_int);
int rt_ifa_add(struct ifaddr *, int, struct sockaddr *);
int rt_ifa_del(struct ifaddr *, int, struct sockaddr *);
void rt_ifa_purge(struct ifaddr *);
diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c
index 7fdc5291892..f1fc135f374 100644
--- a/sys/net/rtsock.c
+++ b/sys/net/rtsock.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rtsock.c,v 1.240 2017/07/03 19:23:47 claudio Exp $ */
+/* $OpenBSD: rtsock.c,v 1.241 2017/07/24 09:20:32 mpi Exp $ */
/* $NetBSD: rtsock.c,v 1.18 1996/03/29 00:32:10 cgd Exp $ */
/*
@@ -82,6 +82,10 @@
#ifdef MPLS
#include <netmpls/mpls.h>
#endif
+#ifdef IPSEC
+#include <netinet/ip_ipsp.h>
+#include <net/if_enc.h>
+#endif
#ifdef BFD
#include <net/bfd.h>
#endif
@@ -109,6 +113,7 @@ int route_arp_conflict(struct rtentry *, struct rt_addrinfo *);
int route_cleargateway(struct rtentry *, void *, unsigned int);
void route_senddesync(void *);
+int rtm_getifa(struct rt_addrinfo *, unsigned int);
int rtm_output(struct rt_msghdr *, struct rtentry **, struct rt_addrinfo *,
uint8_t, unsigned int);
struct rt_msghdr *rtm_report(struct rtentry *, u_char, int, int);
@@ -767,6 +772,8 @@ rtm_output(struct rt_msghdr *rtm, struct rtentry **prt,
rtfree(rt);
rt = NULL;
+ if ((error = rtm_getifa(info, tableid)) != 0)
+ break;
error = rtrequest(RTM_ADD, info, prio, &rt, tableid);
if (error == 0)
rtm_setmetrics(rtm->rtm_inits, &rtm->rtm_rmx,
@@ -880,7 +887,7 @@ rtm_output(struct rt_msghdr *rtm, struct rtentry **prt,
*/
if (newgate || info->rti_info[RTAX_IFP] != NULL ||
info->rti_info[RTAX_IFA] != NULL) {
- if ((error = rt_getifa(info, tableid)) != 0)
+ if ((error = rtm_getifa(info, tableid)) != 0)
break;
ifa = info->rti_ifa;
if (rt->rt_ifa != ifa) {
@@ -1009,6 +1016,120 @@ change:
return (error);
}
+struct ifaddr *
+ifa_ifwithroute(int flags, struct sockaddr *dst, struct sockaddr *gateway,
+ unsigned int rtableid)
+{
+ struct ifaddr *ifa;
+
+ if ((flags & RTF_GATEWAY) == 0) {
+ /*
+ * If we are adding a route to an interface,
+ * and the interface is a pt to pt link
+ * we should search for the destination
+ * as our clue to the interface. Otherwise
+ * we can use the local address.
+ */
+ ifa = NULL;
+ if (flags & RTF_HOST)
+ ifa = ifa_ifwithdstaddr(dst, rtableid);
+ if (ifa == NULL)
+ ifa = ifa_ifwithaddr(gateway, rtableid);
+ } else {
+ /*
+ * If we are adding a route to a remote net
+ * or host, the gateway may still be on the
+ * other end of a pt to pt link.
+ */
+ ifa = ifa_ifwithdstaddr(gateway, rtableid);
+ }
+ if (ifa == NULL) {
+ if (gateway->sa_family == AF_LINK) {
+ struct sockaddr_dl *sdl = satosdl(gateway);
+ struct ifnet *ifp = if_get(sdl->sdl_index);
+
+ if (ifp != NULL)
+ ifa = ifaof_ifpforaddr(dst, ifp);
+ if_put(ifp);
+ } else {
+ struct rtentry *rt;
+
+ rt = rtalloc(gateway, RT_RESOLVE, rtable_l2(rtableid));
+ if (rt != NULL)
+ ifa = rt->rt_ifa;
+ rtfree(rt);
+ }
+ }
+ if (ifa == NULL)
+ return (NULL);
+ if (ifa->ifa_addr->sa_family != dst->sa_family) {
+ struct ifaddr *oifa = ifa;
+ ifa = ifaof_ifpforaddr(dst, ifa->ifa_ifp);
+ if (ifa == NULL)
+ ifa = oifa;
+ }
+ return (ifa);
+}
+
+int
+rtm_getifa(struct rt_addrinfo *info, unsigned int rtid)
+{
+ struct ifnet *ifp = NULL;
+
+ /*
+ * ifp may be specified by sockaddr_dl when protocol address
+ * is ambiguous
+ */
+ if (info->rti_info[RTAX_IFP] != NULL) {
+ struct sockaddr_dl *sdl;
+
+ sdl = satosdl(info->rti_info[RTAX_IFP]);
+ ifp = if_get(sdl->sdl_index);
+ }
+
+#ifdef IPSEC
+ /*
+ * If the destination is a PF_KEY address, we'll look
+ * for the existence of a encap interface number or address
+ * in the options list of the gateway. By default, we'll return
+ * enc0.
+ */
+ if (info->rti_info[RTAX_DST] &&
+ info->rti_info[RTAX_DST]->sa_family == PF_KEY)
+ info->rti_ifa = enc_getifa(rtid, 0);
+#endif
+
+ if (info->rti_ifa == NULL && info->rti_info[RTAX_IFA] != NULL)
+ info->rti_ifa = ifa_ifwithaddr(info->rti_info[RTAX_IFA], rtid);
+
+ if (info->rti_ifa == NULL) {
+ struct sockaddr *sa;
+
+ if ((sa = info->rti_info[RTAX_IFA]) == NULL)
+ if ((sa = info->rti_info[RTAX_GATEWAY]) == NULL)
+ sa = info->rti_info[RTAX_DST];
+
+ if (sa != NULL && ifp != NULL)
+ info->rti_ifa = ifaof_ifpforaddr(sa, ifp);
+ else if (info->rti_info[RTAX_DST] != NULL &&
+ info->rti_info[RTAX_GATEWAY] != NULL)
+ info->rti_ifa = ifa_ifwithroute(info->rti_flags,
+ info->rti_info[RTAX_DST],
+ info->rti_info[RTAX_GATEWAY],
+ rtid);
+ else if (sa != NULL)
+ info->rti_ifa = ifa_ifwithroute(info->rti_flags,
+ sa, sa, rtid);
+ }
+
+ if_put(ifp);
+
+ if (info->rti_ifa == NULL)
+ return (ENETUNREACH);
+
+ return (0);
+}
+
int
route_cleargateway(struct rtentry *rt, void *arg, unsigned int rtableid)
{