X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/39236c6e673c41db228275375ab7fdb0f837b292..4d15aeb193b2c68f1d38666c317f8d3734f5f083:/bsd/netinet6/ip6_forward.c?ds=sidebyside diff --git a/bsd/netinet6/ip6_forward.c b/bsd/netinet6/ip6_forward.c index 6fdaa1069..e6beab89a 100644 --- a/bsd/netinet6/ip6_forward.c +++ b/bsd/netinet6/ip6_forward.c @@ -1,8 +1,8 @@ /* - * Copyright (c) 2009-2013 Apple Inc. All rights reserved. + * Copyright (c) 2009-2016 Apple Inc. All rights reserved. * * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ - * + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -11,10 +11,10 @@ * unlawful or unlicensed copies of an Apple operating system, or to * circumvent, violate, or enable the circumvention or violation of, any * terms of an Apple operating system software license agreement. - * + * * Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this file. - * + * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, @@ -22,7 +22,7 @@ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. - * + * * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ */ @@ -97,10 +97,13 @@ extern int ipsec_bypass; #endif /* IPSEC */ -#include - #include +#if DUMMYNET +#include +#include +#endif /* DUMMYNET */ + #if PF #include #endif /* PF */ @@ -198,8 +201,7 @@ ip6_forward(struct mbuf *m, struct route_in6 *ip6forward_rt, #endif /*IPSEC*/ /* - * Do not forward packets to multicast destination (should be handled - * by ip6_mforward(). + * Do not forward packets to multicast destination. * Do not forward packets with unspecified source. It was discussed * in July 2000, on ipngwg mailing list. */ @@ -224,8 +226,8 @@ ip6_forward(struct mbuf *m, struct route_in6 *ip6forward_rt, if (ip6->ip6_hlim <= IPV6_HLIMDEC) { /* XXX in6_ifstat_inc(rt->rt_ifp, ifs6_in_discard) */ - icmp6_error(m, ICMP6_TIME_EXCEEDED, - ICMP6_TIME_EXCEED_TRANSIT, 0); + icmp6_error_flag(m, ICMP6_TIME_EXCEEDED, + ICMP6_TIME_EXCEED_TRANSIT, 0, 0); return (NULL); } @@ -473,6 +475,8 @@ ip6_forward(struct mbuf *m, struct route_in6 *ip6forward_rt, */ src_in6 = ip6->ip6_src; if (in6_setscope(&src_in6, rt->rt_ifp, &outzone)) { + RT_REMREF_LOCKED(rt); + RT_UNLOCK(rt); /* XXX: this should not happen */ ip6stat.ip6s_cantforward++; ip6stat.ip6s_badscope++; @@ -480,6 +484,8 @@ ip6_forward(struct mbuf *m, struct route_in6 *ip6forward_rt, return (NULL); } if (in6_setscope(&src_in6, m->m_pkthdr.rcvif, &inzone)) { + RT_REMREF_LOCKED(rt); + RT_UNLOCK(rt); ip6stat.ip6s_cantforward++; ip6stat.ip6s_badscope++; m_freem(m); @@ -523,6 +529,8 @@ ip6_forward(struct mbuf *m, struct route_in6 *ip6forward_rt, if (in6_setscope(&dst_in6, m->m_pkthdr.rcvif, &inzone) != 0 || in6_setscope(&dst_in6, rt->rt_ifp, &outzone) != 0 || inzone != outzone) { + RT_REMREF_LOCKED(rt); + RT_UNLOCK(rt); ip6stat.ip6s_cantforward++; ip6stat.ip6s_badscope++; m_freem(m); @@ -612,29 +620,6 @@ ip6_forward(struct mbuf *m, struct route_in6 *ip6forward_rt, } type = ND_REDIRECT; } - -#if IPFW2 - /* - * Check with the firewall... - */ - if (ip6_fw_enable && ip6_fw_chk_ptr) { - u_short port = 0; - ifp = rt->rt_ifp; - /* Drop the lock but retain the extra ref */ - RT_UNLOCK(rt); - /* If ipfw says divert, we have to just drop packet */ - if (ip6_fw_chk_ptr(&ip6, ifp, &port, &m)) { - m_freem(m); - goto freecopy; - } - if (!m) { - goto freecopy; - } - /* We still have the extra ref on rt */ - RT_LOCK(rt); - } -#endif - /* * Fake scoped addresses. Note that even link-local source or * destinaion can appear, if the originating node just sends the @@ -654,7 +639,7 @@ ip6_forward(struct mbuf *m, struct route_in6 *ip6forward_rt, * rthdr. (itojun) */ #if 1 - if (0) + if ((0)) #else if ((rt->rt_flags & (RTF_BLACKHOLE|RTF_REJECT)) == 0) #endif @@ -704,25 +689,47 @@ ip6_forward(struct mbuf *m, struct route_in6 *ip6forward_rt, return (m); } -#if PF - /* Invoke outbound packet filter */ - error = pf_af_hook(ifp, NULL, &m, AF_INET6, FALSE, NULL); + /* Mark this packet as being forwarded from another interface */ + m->m_pkthdr.pkt_flags |= PKTF_FORWARDED; - if (error != 0 || m == NULL) { - if (m != NULL) { - panic("%s: unexpected packet %p\n", __func__, m); - /* NOTREACHED */ +#if PF + if (PF_IS_ENABLED) { +#if DUMMYNET + struct ip_fw_args args; + bzero(&args, sizeof(args)); + + args.fwa_m = m; + args.fwa_oif = ifp; + args.fwa_oflags = 0; + args.fwa_ro6 = ip6forward_rt; + args.fwa_ro6_pmtu = ip6forward_rt; + args.fwa_mtu = rt->rt_ifp->if_mtu; + args.fwa_dst6 = dst; + args.fwa_origifp = origifp; + /* Invoke outbound packet filter */ + error = pf_af_hook(ifp, NULL, &m, AF_INET6, FALSE, &args); +#else /* !DUMMYNET */ + error = pf_af_hook(ifp, NULL, &m, AF_INET6, FALSE, NULL); +#endif /* !DUMMYNET */ + if (error != 0 || m == NULL) { + if (m != NULL) { + panic("%s: unexpected packet %p\n", __func__, m); + /* NOTREACHED */ + } + /* Already freed by callee */ + goto senderr; } - /* Already freed by callee */ - goto senderr; + /* + * We do not use ip6 header again in the code below, + * however still adding the bit here so that any new + * code in future doesn't end up working with the + * wrong pointer + */ + ip6 = mtod(m, struct ip6_hdr *); } - ip6 = mtod(m, struct ip6_hdr *); #endif /* PF */ - /* Mark this packet as being forwarded from another interface */ - m->m_pkthdr.pkt_flags |= PKTF_FORWARDED; len = m_pktlen(m); - error = nd6_output(ifp, origifp, m, dst, rt, NULL); if (error) { in6_ifstat_inc(ifp, ifs6_out_discard);