X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/55e303ae13a4cf49d70f2294092726f2fffb9ef2..b0d623f7f2ae71ed96e60569f61f9a9a27016e80:/bsd/netinet6/mld6.c?ds=inline diff --git a/bsd/netinet6/mld6.c b/bsd/netinet6/mld6.c index 7b1b091ce..36e09c8b8 100644 --- a/bsd/netinet6/mld6.c +++ b/bsd/netinet6/mld6.c @@ -1,3 +1,31 @@ +/* + * Copyright (c) 2008 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 + * compliance with the License. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * 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, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * 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@ + */ + /* $FreeBSD: src/sys/netinet6/mld6.c,v 1.4.2.2 2001/07/03 11:01:54 ume Exp $ */ /* $KAME: mld6.c,v 1.27 2001/04/04 05:17:30 itojun Exp $ */ @@ -68,7 +96,12 @@ * * @(#)igmp.c 8.1 (Berkeley) 7/19/93 */ - +/* + * NOTICE: This file was modified by SPARTA, Inc. in 2005 to introduce + * support for mandatory and extensible security protections. This notice + * is included in support of clause 2.2 (b) of the Apple Public License, + * Version 2.0. + */ #include #include @@ -88,6 +121,10 @@ #include +#if CONFIG_MACF_NET +#include +#endif /* MAC_NET */ + /* * Protocol constants */ @@ -100,6 +137,7 @@ */ #define MLD6_UNSOLICITED_REPORT_INTERVAL 10 +extern lck_mtx_t *nd6_mutex; static struct ip6_pktopts ip6_opts; static int mld6_timers_are_running; static int mld6_init_done = 0 ; @@ -107,7 +145,7 @@ static int mld6_init_done = 0 ; static struct in6_addr mld6_all_nodes_linklocal = IN6ADDR_LINKLOCAL_ALLNODES_INIT; static struct in6_addr mld6_all_routers_linklocal = IN6ADDR_LINKLOCAL_ALLROUTERS_INIT; -static void mld6_sendpkt __P((struct in6_multi *, int, const struct in6_addr *)); +static void mld6_sendpkt(struct in6_multi *, int, const struct in6_addr *); void mld6_init() @@ -132,16 +170,14 @@ mld6_init() hbh_buf[5] = IP6OPT_RTALERT_LEN - 2; bcopy((caddr_t)&rtalert_code, &hbh_buf[6], sizeof(u_int16_t)); - init_ip6pktopts(&ip6_opts); + ip6_initpktopts(&ip6_opts); ip6_opts.ip6po_hbh = hbh; } void -mld6_start_listening(in6m) - struct in6_multi *in6m; +mld6_start_listening( + struct in6_multi *in6m) { - int s = splnet(); - /* * RFC2710 page 10: * The node never sends a Report or Done for the link-scope all-nodes @@ -162,12 +198,11 @@ mld6_start_listening(in6m) in6m->in6m_state = MLD6_IREPORTEDLAST; mld6_timers_are_running = 1; } - splx(s); } void -mld6_stop_listening(in6m) - struct in6_multi *in6m; +mld6_stop_listening( + struct in6_multi *in6m) { mld6_all_nodes_linklocal.s6_addr16[1] = htons(in6m->in6m_ifp->if_index); /* XXX */ @@ -182,9 +217,9 @@ mld6_stop_listening(in6m) } void -mld6_input(m, off) - struct mbuf *m; - int off; +mld6_input( + struct mbuf *m, + int off) { struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *); struct mld6_hdr *mldh; @@ -195,7 +230,7 @@ mld6_input(m, off) int timer; /* timer value in the MLD query header */ #ifndef PULLDOWN_TEST - IP6_EXTHDR_CHECK(m, off, sizeof(*mldh),); + IP6_EXTHDR_CHECK(m, off, sizeof(*mldh), return); mldh = (struct mld6_hdr *)(mtod(m, caddr_t) + off); #else IP6_EXTHDR_GET(mldh, struct mld6_hdr *, m, off, sizeof(*mldh)); @@ -255,6 +290,7 @@ mld6_input(m, off) * - Use the value specified in the query message as * the maximum timeout. */ + ifnet_lock_exclusive(ifp); IFP_TO_IA6(ifp, ia); if (ia == NULL) break; @@ -301,6 +337,7 @@ mld6_input(m, off) } } } + ifnet_lock_done(ifp); if (IN6_IS_ADDR_MC_LINKLOCAL(&mldh->mld6_addr)) mldh->mld6_addr.s6_addr16[1] = 0; /* XXX */ @@ -328,11 +365,13 @@ mld6_input(m, off) * If we belong to the group being reported, stop * our timer for that group. */ + ifnet_lock_shared(ifp); IN6_LOOKUP_MULTI(mldh->mld6_addr, ifp, in6m); if (in6m) { in6m->in6m_timer = 0; /* transit to idle state */ in6m->in6m_state = MLD6_OTHERLISTENER; /* clear flag */ } + ifnet_lock_done(ifp); if (IN6_IS_ADDR_MC_LINKLOCAL(&mldh->mld6_addr)) mldh->mld6_addr.s6_addr16[1] = 0; /* XXX */ @@ -350,7 +389,6 @@ mld6_fasttimeo() { struct in6_multi *in6m; struct in6_multistep step; - int s; /* * Quick check to see if any work needs to be done, in order @@ -359,7 +397,7 @@ mld6_fasttimeo() if (!mld6_timers_are_running) return; - s = splnet(); + lck_mtx_lock(nd6_mutex); mld6_timers_are_running = 0; IN6_FIRST_MULTI(step, in6m); while (in6m != NULL) { @@ -373,14 +411,14 @@ mld6_fasttimeo() } IN6_NEXT_MULTI(step, in6m); } - splx(s); + lck_mtx_unlock(nd6_mutex); } static void -mld6_sendpkt(in6m, type, dst) - struct in6_multi *in6m; - int type; - const struct in6_addr *dst; +mld6_sendpkt( + struct in6_multi *in6m, + int type, + const struct in6_addr *dst) { struct mbuf *mh, *md; struct mld6_hdr *mldh; @@ -404,16 +442,24 @@ mld6_sendpkt(in6m, type, dst) * it is more convenient when inserting the hop-by-hop option later. */ MGETHDR(mh, M_DONTWAIT, MT_HEADER); - if (mh == NULL) + if (mh == NULL) { + ifafree(&ia->ia_ifa); return; + } MGET(md, M_DONTWAIT, MT_DATA); if (md == NULL) { m_free(mh); + ifafree(&ia->ia_ifa); return; } mh->m_next = md; mh->m_pkthdr.rcvif = NULL; +#ifdef __darwin8_notyet +#if CONFIG_MACF_NET + mac_create_mbuf_linklayer(in6m->in6m_ifp, m); +#endif +#endif mh->m_pkthdr.len = sizeof(struct ip6_hdr) + sizeof(struct mld6_hdr); mh->m_len = sizeof(struct ip6_hdr); MH_ALIGN(mh, sizeof(struct ip6_hdr)); @@ -458,7 +504,7 @@ mld6_sendpkt(in6m, type, dst) /* increment output statictics */ icmp6stat.icp6s_outhist[type]++; - ip6_output(mh, &ip6_opts, NULL, 0, &im6o, &outif); + ip6_output(mh, &ip6_opts, NULL, 0, &im6o, &outif, 0); if (outif) { icmp6_ifstat_inc(outif, ifs6_out_msg); switch (type) { @@ -473,4 +519,6 @@ mld6_sendpkt(in6m, type, dst) break; } } + ifafree(&ia->ia_ifa); } +