summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormpi <mpi@openbsd.org>2015-09-11 13:53:04 +0000
committermpi <mpi@openbsd.org>2015-09-11 13:53:04 +0000
commitb9ab5338167920ba112eba75026aae3dd903aaa4 (patch)
tree17bf8f96d934a1330876924d35e97e894b2d039e
parentsync (diff)
downloadwireguard-openbsd-b9ab5338167920ba112eba75026aae3dd903aaa4.tar.xz
wireguard-openbsd-b9ab5338167920ba112eba75026aae3dd903aaa4.zip
Move the multicast option parsing out of in6_selectroute().
ok claudio@
-rw-r--r--sys/netinet6/in6_src.c54
-rw-r--r--sys/netinet6/ip6_output.c32
-rw-r--r--sys/netinet6/ip6_var.h6
3 files changed, 45 insertions, 47 deletions
diff --git a/sys/netinet6/in6_src.c b/sys/netinet6/in6_src.c
index e3e3b436f41..46858a1dc2a 100644
--- a/sys/netinet6/in6_src.c
+++ b/sys/netinet6/in6_src.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: in6_src.c,v 1.58 2015/09/11 09:58:33 mpi Exp $ */
+/* $OpenBSD: in6_src.c,v 1.59 2015/09/11 13:53:04 mpi Exp $ */
/* $KAME: in6_src.c,v 1.36 2001/02/06 04:08:17 itojun Exp $ */
/*
@@ -295,43 +295,17 @@ in6_selectsrc(struct in6_addr **in6src, struct sockaddr_in6 *dstsock,
int
in6_selectroute(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts,
- struct ip6_moptions *mopts, struct route_in6 *ro, struct ifnet **retifp,
- struct rtentry **retrt, int norouteok, u_int rtableid)
+ struct route_in6 *ro, struct ifnet **retifp,
+ struct rtentry **retrt, unsigned int rtableid)
{
int error = 0;
struct ifnet *ifp = NULL;
struct rtentry *rt = NULL;
struct sockaddr_in6 *sin6_next;
- struct in6_pktinfo *pi = NULL;
struct in6_addr *dst;
dst = &dstsock->sin6_addr;
- /* If the caller specify the outgoing interface explicitly, use it. */
- if (opts && (pi = opts->ip6po_pktinfo) != NULL && pi->ipi6_ifindex) {
- ifp = if_get(pi->ipi6_ifindex);
- if (ifp != NULL &&
- (norouteok || retrt == NULL ||
- IN6_IS_ADDR_MULTICAST(dst))) {
- /*
- * we do not have to check or get the route for
- * multicast.
- */
- goto done;
- } else
- goto getroute;
- }
-
- /*
- * If the destination address is a multicast address and the outgoing
- * interface for the address is specified by the caller, use it.
- */
- if (IN6_IS_ADDR_MULTICAST(dst) &&
- mopts != NULL && (ifp = if_get(mopts->im6o_ifidx)) != NULL) {
- goto done; /* we do not need a route for multicast. */
- }
-
- getroute:
/*
* If the next hop address for the packet is specified by the caller,
* use it as the gateway.
@@ -467,8 +441,6 @@ in6_selectroute(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts,
*/
error = EHOSTUNREACH;
}
- if (error == EHOSTUNREACH)
- ip6stat.ip6s_noroute++;
if (retifp != NULL)
*retifp = ifp;
@@ -484,10 +456,26 @@ in6_selectif(struct sockaddr_in6 *dstsock, struct ip6_pktopts *opts,
u_int rtableid)
{
struct rtentry *rt = NULL;
+ struct in6_pktinfo *pi = NULL;
int error;
- if ((error = in6_selectroute(dstsock, opts, mopts, ro, retifp,
- &rt, 1, rtableid)) != 0)
+ /* If the caller specify the outgoing interface explicitly, use it. */
+ if (opts && (pi = opts->ip6po_pktinfo) != NULL && pi->ipi6_ifindex) {
+ *retifp = if_get(pi->ipi6_ifindex);
+ if (*retifp != NULL)
+ return (0);
+ }
+
+ /*
+ * If the destination address is a multicast address and the outgoing
+ * interface for the address is specified by the caller, use it.
+ */
+ if (IN6_IS_ADDR_MULTICAST(&dstsock->sin6_addr) &&
+ mopts != NULL && (*retifp = if_get(mopts->im6o_ifidx)) != NULL)
+ return (0);
+
+ if ((error = in6_selectroute(dstsock, opts, ro, retifp,
+ &rt, rtableid)) != 0)
return (error);
/*
diff --git a/sys/netinet6/ip6_output.c b/sys/netinet6/ip6_output.c
index 6a6fcaf8e03..44167d3ac22 100644
--- a/sys/netinet6/ip6_output.c
+++ b/sys/netinet6/ip6_output.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip6_output.c,v 1.182 2015/09/11 09:58:33 mpi Exp $ */
+/* $OpenBSD: ip6_output.c,v 1.183 2015/09/11 13:53:04 mpi Exp $ */
/* $KAME: ip6_output.c,v 1.172 2001/03/25 09:55:56 itojun Exp $ */
/*
@@ -155,7 +155,7 @@ ip6_output(struct mbuf *m0, struct ip6_pktopts *opt, struct route_in6 *ro,
int flags, struct ip6_moptions *im6o, struct inpcb *inp)
{
struct ip6_hdr *ip6;
- struct ifnet *ifp;
+ struct ifnet *ifp = NULL;
struct mbuf *m = m0;
int hlen, tlen;
struct route_in6 ip6route;
@@ -528,17 +528,27 @@ reroute:
dstsock.sin6_addr = ip6->ip6_dst;
dstsock.sin6_len = sizeof(dstsock);
ro->ro_tableid = m->m_pkthdr.ph_rtableid;
- if ((error = in6_selectroute(&dstsock, opt, im6o, ro, &ifp,
- &rt, 0, m->m_pkthdr.ph_rtableid)) != 0) {
- switch (error) {
- case EHOSTUNREACH:
+
+ if (IN6_IS_ADDR_MULTICAST(&dstsock.sin6_addr)) {
+ struct in6_pktinfo *pi = NULL;
+
+ /*
+ * If the caller specify the outgoing interface
+ * explicitly, use it.
+ */
+ if (opt != NULL && (pi = opt->ip6po_pktinfo) != NULL)
+ ifp = if_get(pi->ipi6_ifindex);
+
+ if (ifp == NULL && im6o != NULL)
+ ifp = if_get(im6o->im6o_ifidx);
+ }
+
+ if (ifp == NULL) {
+ if ((error = in6_selectroute(&dstsock, opt, ro, &ifp,
+ &rt, m->m_pkthdr.ph_rtableid)) != 0) {
ip6stat.ip6s_noroute++;
- break;
- case EADDRNOTAVAIL:
- default:
- break; /* XXX statistics? */
+ goto bad;
}
- goto bad;
}
if (rt == NULL) {
/*
diff --git a/sys/netinet6/ip6_var.h b/sys/netinet6/ip6_var.h
index 9576a2e6b6e..26b3930e1b3 100644
--- a/sys/netinet6/ip6_var.h
+++ b/sys/netinet6/ip6_var.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip6_var.h,v 1.53 2015/09/11 09:58:33 mpi Exp $ */
+/* $OpenBSD: ip6_var.h,v 1.54 2015/09/11 13:53:04 mpi Exp $ */
/* $KAME: ip6_var.h,v 1.33 2000/06/11 14:59:20 jinmei Exp $ */
/*
@@ -311,8 +311,8 @@ int in6_selectsrc(struct in6_addr **, struct sockaddr_in6 *,
struct ip6_pktopts *, struct ip6_moptions *, struct route_in6 *,
struct in6_addr *, u_int);
int in6_selectroute(struct sockaddr_in6 *, struct ip6_pktopts *,
- struct ip6_moptions *, struct route_in6 *, struct ifnet **,
- struct rtentry **, int, u_int rtableid);
+ struct route_in6 *, struct ifnet **,
+ struct rtentry **, unsigned int rtableid);
u_int32_t ip6_randomflowlabel(void);
#endif /* _KERNEL */