X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/e2fac8b15b12a7979f72090454d850e612fc5b13..b0d623f7f2ae71ed96e60569f61f9a9a27016e80:/bsd/netinet/in_gif.c diff --git a/bsd/netinet/in_gif.c b/bsd/netinet/in_gif.c index 787c688ce..482aef5e4 100644 --- a/bsd/netinet/in_gif.c +++ b/bsd/netinet/in_gif.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2007 Apple Inc. All rights reserved. + * Copyright (c) 2000-2008 Apple Inc. All rights reserved. * * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * @@ -93,8 +93,6 @@ #include -extern u_long route_generation; - int ip_gif_ttl = GIF_TTL; SYSCTL_INT(_net_inet_ip, IPCTL_GIF_TTL, gifttl, CTLFLAG_RW, &ip_gif_ttl, 0, ""); @@ -196,7 +194,7 @@ in_gif_output( (sc->gif_ro.ro_rt != NULL && (sc->gif_ro.ro_rt->generation_id != route_generation || sc->gif_ro.ro_rt->rt_ifp == ifp))) { - /* cache route doesn't match */ + /* cache route doesn't match or recursive route */ dst->sin_family = sin_dst->sin_family; dst->sin_len = sizeof(struct sockaddr_in); dst->sin_addr = sin_dst->sin_addr; @@ -217,7 +215,9 @@ in_gif_output( } /* if it constitutes infinite encapsulation, punt. */ + RT_LOCK(sc->gif_ro.ro_rt); if (sc->gif_ro.ro_rt->rt_ifp == ifp) { + RT_UNLOCK(sc->gif_ro.ro_rt); m_freem(m); return ENETUNREACH; /*XXX*/ } @@ -225,6 +225,7 @@ in_gif_output( ifp->if_mtu = sc->gif_ro.ro_rt->rt_ifp->if_mtu - sizeof(struct ip); #endif + RT_UNLOCK(sc->gif_ro.ro_rt); } error = ip_output(m, NULL, &sc->gif_ro, IP_OUTARGS, NULL, &ipoa); @@ -249,7 +250,7 @@ in_gif_input(m, off) if (gifp == NULL || (gifp->if_flags & IFF_UP) == 0) { m_freem(m); - OSAddAtomic(1, (SInt32*)&ipstat.ips_nogif); + OSAddAtomic(1, &ipstat.ips_nogif); return; } @@ -297,7 +298,7 @@ in_gif_input(m, off) } #endif /* INET6 */ default: - OSAddAtomic(1, (SInt32*)&ipstat.ips_nogif); + OSAddAtomic(1, &ipstat.ips_nogif); m_freem(m); return; } @@ -345,7 +346,7 @@ gif_encapcheck4( src = (struct sockaddr_in *)sc->gif_psrc; dst = (struct sockaddr_in *)sc->gif_pdst; - mbuf_copydata(m, 0, sizeof(ip), &ip); + mbuf_copydata((struct mbuf *)(size_t)m, 0, sizeof(ip), &ip); /* check for address match */ addrmatch = 0; @@ -364,18 +365,18 @@ gif_encapcheck4( return 0; } /* reject packets with broadcast on source */ - lck_mtx_lock(rt_mtx); + lck_rw_lock_shared(in_ifaddr_rwlock); for (ia4 = TAILQ_FIRST(&in_ifaddrhead); ia4; ia4 = TAILQ_NEXT(ia4, ia_link)) { if ((ifnet_flags(ia4->ia_ifa.ifa_ifp) & IFF_BROADCAST) == 0) continue; if (ip.ip_src.s_addr == ia4->ia_broadaddr.sin_addr.s_addr) { - lck_mtx_unlock(rt_mtx); + lck_rw_done(in_ifaddr_rwlock); return 0; } } - lck_mtx_unlock(rt_mtx); + lck_rw_done(in_ifaddr_rwlock); /* ingress filters on outer source */ if ((ifnet_flags(sc->gif_if) & IFF_LINK2) == 0 && @@ -387,20 +388,23 @@ gif_encapcheck4( sin.sin_family = AF_INET; sin.sin_len = sizeof(struct sockaddr_in); sin.sin_addr = ip.ip_src; - lck_mtx_lock(rt_mtx); - rt = rtalloc1_scoped_locked((struct sockaddr *)&sin, 0, 0, + rt = rtalloc1_scoped((struct sockaddr *)&sin, 0, 0, m->m_pkthdr.rcvif->if_index); - lck_mtx_unlock(rt_mtx); - if (!rt || rt->rt_ifp != m->m_pkthdr.rcvif) { + if (rt != NULL) + RT_LOCK(rt); + if (rt == NULL || rt->rt_ifp != m->m_pkthdr.rcvif) { #if 0 log(LOG_WARNING, "%s: packet from 0x%x dropped " "due to ingress filter\n", if_name(&sc->gif_if), (u_int32_t)ntohl(sin.sin_addr.s_addr)); #endif - if (rt) + if (rt != NULL) { + RT_UNLOCK(rt); rtfree(rt); + } return 0; } + RT_UNLOCK(rt); rtfree(rt); }