diff options
author | 2015-09-11 13:53:04 +0000 | |
---|---|---|
committer | 2015-09-11 13:53:04 +0000 | |
commit | b9ab5338167920ba112eba75026aae3dd903aaa4 (patch) | |
tree | 17bf8f96d934a1330876924d35e97e894b2d039e | |
parent | sync (diff) | |
download | wireguard-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.c | 54 | ||||
-rw-r--r-- | sys/netinet6/ip6_output.c | 32 | ||||
-rw-r--r-- | sys/netinet6/ip6_var.h | 6 |
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 */ |