xref: /xnu-8020.121.3/bsd/netinet/igmp.c (revision fdd8201d7b966f0c3ea610489d29bd841d358941)
1 /*
2  * Copyright (c) 2000-2020 Apple Inc. All rights reserved.
3  *
4  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5  *
6  * This file contains Original Code and/or Modifications of Original Code
7  * as defined in and that are subject to the Apple Public Source License
8  * Version 2.0 (the 'License'). You may not use this file except in
9  * compliance with the License. The rights granted to you under the License
10  * may not be used to create, or enable the creation or redistribution of,
11  * unlawful or unlicensed copies of an Apple operating system, or to
12  * circumvent, violate, or enable the circumvention or violation of, any
13  * terms of an Apple operating system software license agreement.
14  *
15  * Please obtain a copy of the License at
16  * http://www.opensource.apple.com/apsl/ and read it before using this file.
17  *
18  * The Original Code and all software distributed under the License are
19  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23  * Please see the License for the specific language governing rights and
24  * limitations under the License.
25  *
26  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27  */
28 /*-
29  * Copyright (c) 2007-2009 Bruce Simpson.
30  * Copyright (c) 1988 Stephen Deering.
31  * Copyright (c) 1992, 1993
32  *	The Regents of the University of California.  All rights reserved.
33  *
34  * This code is derived from software contributed to Berkeley by
35  * Stephen Deering of Stanford University.
36  *
37  * Redistribution and use in source and binary forms, with or without
38  * modification, are permitted provided that the following conditions
39  * are met:
40  * 1. Redistributions of source code must retain the above copyright
41  *    notice, this list of conditions and the following disclaimer.
42  * 2. Redistributions in binary form must reproduce the above copyright
43  *    notice, this list of conditions and the following disclaimer in the
44  *    documentation and/or other materials provided with the distribution.
45  * 3. All advertising materials mentioning features or use of this software
46  *    must display the following acknowledgement:
47  *	This product includes software developed by the University of
48  *	California, Berkeley and its contributors.
49  * 4. Neither the name of the University nor the names of its contributors
50  *    may be used to endorse or promote products derived from this software
51  *    without specific prior written permission.
52  *
53  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
54  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
55  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
56  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
57  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
58  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
59  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
60  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
61  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
62  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
63  * SUCH DAMAGE.
64  *
65  *	@(#)igmp.c	8.1 (Berkeley) 7/19/93
66  */
67 /*
68  * NOTICE: This file was modified by SPARTA, Inc. in 2005 to introduce
69  * support for mandatory and extensible security protections.  This notice
70  * is included in support of clause 2.2 (b) of the Apple Public License,
71  * Version 2.0.
72  */
73 
74 /*
75  * Internet Group Management Protocol (IGMP) routines.
76  * [RFC1112, RFC2236, RFC3376]
77  *
78  * Written by Steve Deering, Stanford, May 1988.
79  * Modified by Rosen Sharma, Stanford, Aug 1994.
80  * Modified by Bill Fenner, Xerox PARC, Feb 1995.
81  * Modified to fully comply to IGMPv2 by Bill Fenner, Oct 1995.
82  * Significantly rewritten for IGMPv3, VIMAGE, and SMP by Bruce Simpson.
83  *
84  * MULTICAST Revision: 3.5.1.4
85  */
86 
87 #include <sys/cdefs.h>
88 
89 #include <sys/param.h>
90 #include <sys/systm.h>
91 #include <sys/malloc.h>
92 #include <sys/mbuf.h>
93 #include <sys/socket.h>
94 #include <sys/protosw.h>
95 #include <sys/kernel.h>
96 #include <sys/sysctl.h>
97 #include <sys/mcache.h>
98 
99 #include <libkern/libkern.h>
100 #include <kern/zalloc.h>
101 
102 #include <net/if.h>
103 #include <net/route.h>
104 
105 #include <netinet/in.h>
106 #include <netinet/in_var.h>
107 #include <netinet/in_systm.h>
108 #include <netinet/ip.h>
109 #include <netinet/ip_var.h>
110 #include <netinet/igmp.h>
111 #include <netinet/igmp_var.h>
112 #include <netinet/kpi_ipfilter_var.h>
113 
114 SLIST_HEAD(igmp_inm_relhead, in_multi);
115 
116 static void     igi_initvar(struct igmp_ifinfo *, struct ifnet *, int);
117 static struct igmp_ifinfo *igi_alloc(zalloc_flags_t);
118 static void     igi_free(struct igmp_ifinfo *);
119 static void     igi_delete(const struct ifnet *, struct igmp_inm_relhead *);
120 static void     igmp_dispatch_queue(struct igmp_ifinfo *, struct ifqueue *,
121     int, const int);
122 static void     igmp_final_leave(struct in_multi *, struct igmp_ifinfo *,
123     struct igmp_tparams *);
124 static int      igmp_handle_state_change(struct in_multi *,
125     struct igmp_ifinfo *, struct igmp_tparams *);
126 static int      igmp_initial_join(struct in_multi *, struct igmp_ifinfo *,
127     struct igmp_tparams *);
128 static int      igmp_input_v1_query(struct ifnet *, const struct ip *,
129     const struct igmp *);
130 static int      igmp_input_v2_query(struct ifnet *, const struct ip *,
131     const struct igmp *);
132 static int      igmp_input_v3_query(struct ifnet *, const struct ip *,
133     /*const*/ struct igmpv3 *);
134 static int      igmp_input_v3_group_query(struct in_multi *,
135     int, /*const*/ struct igmpv3 *);
136 static int      igmp_input_v1_report(struct ifnet *, struct mbuf *,
137     /*const*/ struct ip *, /*const*/ struct igmp *);
138 static int      igmp_input_v2_report(struct ifnet *, struct mbuf *,
139     /*const*/ struct ip *, /*const*/ struct igmp *);
140 static void     igmp_sendpkt(struct mbuf *);
141 static __inline__ int   igmp_isgroupreported(const struct in_addr);
142 static struct mbuf *igmp_ra_alloc(void);
143 #ifdef IGMP_DEBUG
144 static const char *igmp_rec_type_to_str(const int);
145 #endif
146 static uint32_t igmp_set_version(struct igmp_ifinfo *, const int);
147 static void     igmp_flush_relq(struct igmp_ifinfo *,
148     struct igmp_inm_relhead *);
149 static int      igmp_v1v2_queue_report(struct in_multi *, const int);
150 static void     igmp_v1v2_process_group_timer(struct in_multi *, const int);
151 static void     igmp_v1v2_process_querier_timers(struct igmp_ifinfo *);
152 static uint32_t igmp_v2_update_group(struct in_multi *, const int);
153 static void     igmp_v3_cancel_link_timers(struct igmp_ifinfo *);
154 static uint32_t igmp_v3_dispatch_general_query(struct igmp_ifinfo *);
155 static struct mbuf *
156 igmp_v3_encap_report(struct ifnet *, struct mbuf *);
157 static int      igmp_v3_enqueue_group_record(struct ifqueue *,
158     struct in_multi *, const int, const int, const int);
159 static int      igmp_v3_enqueue_filter_change(struct ifqueue *,
160     struct in_multi *);
161 static void     igmp_v3_process_group_timers(struct igmp_ifinfo *,
162     struct ifqueue *, struct ifqueue *, struct in_multi *,
163     const unsigned int);
164 static int      igmp_v3_merge_state_changes(struct in_multi *,
165     struct ifqueue *);
166 static void     igmp_v3_suppress_group_record(struct in_multi *);
167 static int      sysctl_igmp_ifinfo SYSCTL_HANDLER_ARGS;
168 static int      sysctl_igmp_gsr SYSCTL_HANDLER_ARGS;
169 static int      sysctl_igmp_default_version SYSCTL_HANDLER_ARGS;
170 
171 static int igmp_timeout_run;            /* IGMP timer is scheduled to run */
172 static void igmp_timeout(void *);
173 static void igmp_sched_timeout(void);
174 
175 static struct mbuf *m_raopt;            /* Router Alert option */
176 
177 static int querier_present_timers_running;      /* IGMPv1/v2 older version
178                                                  * querier present */
179 static int interface_timers_running;            /* IGMPv3 general
180                                                  * query response */
181 static int state_change_timers_running;         /* IGMPv3 state-change
182                                                  * retransmit */
183 static int current_state_timers_running;        /* IGMPv1/v2 host
184                                                  * report; IGMPv3 g/sg
185                                                  * query response */
186 
187 /*
188  * Subsystem lock macros.
189  */
190 #define IGMP_LOCK()                     \
191 	lck_mtx_lock(&igmp_mtx)
192 #define IGMP_LOCK_ASSERT_HELD()         \
193 	LCK_MTX_ASSERT(&igmp_mtx, LCK_MTX_ASSERT_OWNED)
194 #define IGMP_LOCK_ASSERT_NOTHELD()      \
195 	LCK_MTX_ASSERT(&igmp_mtx, LCK_MTX_ASSERT_NOTOWNED)
196 #define IGMP_UNLOCK()                   \
197 	lck_mtx_unlock(&igmp_mtx)
198 
199 static LIST_HEAD(, igmp_ifinfo) igi_head;
200 static struct igmpstat_v3 igmpstat_v3 = {
201 	.igps_version = IGPS_VERSION_3,
202 	.igps_len = sizeof(struct igmpstat_v3),
203 };
204 static struct igmpstat igmpstat; /* old IGMPv2 stats structure */
205 static struct timeval igmp_gsrdelay = {.tv_sec = 10, .tv_usec = 0};
206 
207 static int igmp_recvifkludge = 1;
208 static int igmp_sendra = 1;
209 static int igmp_sendlocal = 1;
210 static int igmp_v1enable = 1;
211 static int igmp_v2enable = 1;
212 static int igmp_legacysupp = 0;
213 static int igmp_default_version = IGMP_VERSION_3;
214 
215 SYSCTL_STRUCT(_net_inet_igmp, IGMPCTL_STATS, stats, CTLFLAG_RD | CTLFLAG_LOCKED,
216     &igmpstat, igmpstat, "");
217 SYSCTL_STRUCT(_net_inet_igmp, OID_AUTO, v3stats,
218     CTLFLAG_RD | CTLFLAG_LOCKED, &igmpstat_v3, igmpstat_v3, "");
219 SYSCTL_INT(_net_inet_igmp, OID_AUTO, recvifkludge, CTLFLAG_RW | CTLFLAG_LOCKED,
220     &igmp_recvifkludge, 0,
221     "Rewrite IGMPv1/v2 reports from 0.0.0.0 to contain subnet address");
222 SYSCTL_INT(_net_inet_igmp, OID_AUTO, sendra, CTLFLAG_RW | CTLFLAG_LOCKED,
223     &igmp_sendra, 0,
224     "Send IP Router Alert option in IGMPv2/v3 messages");
225 SYSCTL_INT(_net_inet_igmp, OID_AUTO, sendlocal, CTLFLAG_RW | CTLFLAG_LOCKED,
226     &igmp_sendlocal, 0,
227     "Send IGMP membership reports for 224.0.0.0/24 groups");
228 SYSCTL_INT(_net_inet_igmp, OID_AUTO, v1enable, CTLFLAG_RW | CTLFLAG_LOCKED,
229     &igmp_v1enable, 0,
230     "Enable backwards compatibility with IGMPv1");
231 SYSCTL_INT(_net_inet_igmp, OID_AUTO, v2enable, CTLFLAG_RW | CTLFLAG_LOCKED,
232     &igmp_v2enable, 0,
233     "Enable backwards compatibility with IGMPv2");
234 SYSCTL_INT(_net_inet_igmp, OID_AUTO, legacysupp, CTLFLAG_RW | CTLFLAG_LOCKED,
235     &igmp_legacysupp, 0,
236     "Allow v1/v2 reports to suppress v3 group responses");
237 SYSCTL_PROC(_net_inet_igmp, OID_AUTO, default_version,
238     CTLTYPE_INT | CTLFLAG_RW,
239     &igmp_default_version, 0, sysctl_igmp_default_version, "I",
240     "Default version of IGMP to run on each interface");
241 SYSCTL_PROC(_net_inet_igmp, OID_AUTO, gsrdelay,
242     CTLTYPE_INT | CTLFLAG_RW,
243     &igmp_gsrdelay.tv_sec, 0, sysctl_igmp_gsr, "I",
244     "Rate limit for IGMPv3 Group-and-Source queries in seconds");
245 #ifdef IGMP_DEBUG
246 int igmp_debug = 0;
247 SYSCTL_INT(_net_inet_igmp, OID_AUTO,
248     debug, CTLFLAG_RW | CTLFLAG_LOCKED, &igmp_debug, 0, "");
249 #endif
250 
251 SYSCTL_NODE(_net_inet_igmp, OID_AUTO, ifinfo, CTLFLAG_RD | CTLFLAG_LOCKED,
252     sysctl_igmp_ifinfo, "Per-interface IGMPv3 state");
253 
254 /* Lock group and attribute for igmp_mtx */
255 static LCK_ATTR_DECLARE(igmp_mtx_attr, 0, 0);
256 static LCK_GRP_DECLARE(igmp_mtx_grp, "igmp_mtx");
257 
258 /*
259  * Locking and reference counting:
260  *
261  * igmp_mtx mainly protects igi_head.  In cases where both igmp_mtx and
262  * in_multihead_lock must be held, the former must be acquired first in order
263  * to maintain lock ordering.  It is not a requirement that igmp_mtx be
264  * acquired first before in_multihead_lock, but in case both must be acquired
265  * in succession, the correct lock ordering must be followed.
266  *
267  * Instead of walking the if_multiaddrs list at the interface and returning
268  * the ifma_protospec value of a matching entry, we search the global list
269  * of in_multi records and find it that way; this is done with in_multihead
270  * lock held.  Doing so avoids the race condition issues that many other BSDs
271  * suffer from (therefore in our implementation, ifma_protospec will never be
272  * NULL for as long as the in_multi is valid.)
273  *
274  * The above creates a requirement for the in_multi to stay in in_multihead
275  * list even after the final IGMP leave (in IGMPv3 mode) until no longer needs
276  * be retransmitted (this is not required for IGMPv1/v2.)  In order to handle
277  * this, the request and reference counts of the in_multi are bumped up when
278  * the state changes to IGMP_LEAVING_MEMBER, and later dropped in the timeout
279  * handler.  Each in_multi holds a reference to the underlying igmp_ifinfo.
280  *
281  * Thus, the permitted lock oder is:
282  *
283  *	igmp_mtx, in_multihead_lock, inm_lock, igi_lock
284  *
285  * Any may be taken independently, but if any are held at the same time,
286  * the above lock order must be followed.
287  */
288 static LCK_MTX_DECLARE_ATTR(igmp_mtx, &igmp_mtx_grp, &igmp_mtx_attr);
289 static int igmp_timers_are_running;
290 
291 #define IGMP_ADD_DETACHED_INM(_head, _inm) {                            \
292 	SLIST_INSERT_HEAD(_head, _inm, inm_dtle);                       \
293 }
294 
295 #define IGMP_REMOVE_DETACHED_INM(_head) {                               \
296 	struct in_multi *_inm, *_inm_tmp;                               \
297 	SLIST_FOREACH_SAFE(_inm, _head, inm_dtle, _inm_tmp) {           \
298 	        SLIST_REMOVE(_head, _inm, in_multi, inm_dtle);          \
299 	        INM_REMREF(_inm);                                       \
300 	}                                                               \
301 	VERIFY(SLIST_EMPTY(_head));                                     \
302 }
303 
304 static ZONE_DEFINE(igi_zone, "igmp_ifinfo",
305     sizeof(struct igmp_ifinfo), ZC_ZFREE_CLEARMEM);
306 
307 /* Store IGMPv3 record count in the module private scratch space */
308 #define vt_nrecs        pkt_mpriv.__mpriv_u.__mpriv32[0].__mpriv32_u.__val16[0]
309 
310 static __inline void
igmp_save_context(struct mbuf * m,struct ifnet * ifp)311 igmp_save_context(struct mbuf *m, struct ifnet *ifp)
312 {
313 	m->m_pkthdr.rcvif = ifp;
314 }
315 
316 static __inline void
igmp_scrub_context(struct mbuf * m)317 igmp_scrub_context(struct mbuf *m)
318 {
319 	m->m_pkthdr.rcvif = NULL;
320 }
321 
322 #ifdef IGMP_DEBUG
323 static __inline const char *
inet_ntop_haddr(in_addr_t haddr,char * buf,socklen_t size)324 inet_ntop_haddr(in_addr_t haddr, char *buf, socklen_t size)
325 {
326 	struct in_addr ia;
327 
328 	ia.s_addr = htonl(haddr);
329 	return inet_ntop(AF_INET, &ia, buf, size);
330 }
331 #endif
332 
333 /*
334  * Restore context from a queued IGMP output chain.
335  * Return saved ifp.
336  */
337 static __inline struct ifnet *
igmp_restore_context(struct mbuf * m)338 igmp_restore_context(struct mbuf *m)
339 {
340 	return m->m_pkthdr.rcvif;
341 }
342 
343 /*
344  * Retrieve or set default IGMP version.
345  */
346 static int
347 sysctl_igmp_default_version SYSCTL_HANDLER_ARGS
348 {
349 #pragma unused(oidp, arg2)
350 	int      error;
351 	int      new;
352 
353 	IGMP_LOCK();
354 
355 	error = SYSCTL_OUT(req, arg1, sizeof(int));
356 	if (error || !req->newptr) {
357 		goto out_locked;
358 	}
359 
360 	new = igmp_default_version;
361 
362 	error = SYSCTL_IN(req, &new, sizeof(int));
363 	if (error) {
364 		goto out_locked;
365 	}
366 
367 	if (new < IGMP_VERSION_1 || new > IGMP_VERSION_3) {
368 		error = EINVAL;
369 		goto out_locked;
370 	}
371 
372 	IGMP_PRINTF(("%s: change igmp_default_version from %d to %d\n",
373 	    __func__, igmp_default_version, new));
374 
375 	igmp_default_version = new;
376 
377 out_locked:
378 	IGMP_UNLOCK();
379 	return error;
380 }
381 
382 /*
383  * Retrieve or set threshold between group-source queries in seconds.
384  *
385  */
386 static int
387 sysctl_igmp_gsr SYSCTL_HANDLER_ARGS
388 {
389 #pragma unused(arg1, arg2)
390 	int error;
391 	int i;
392 
393 	IGMP_LOCK();
394 
395 	i = (int)igmp_gsrdelay.tv_sec;
396 
397 	error = sysctl_handle_int(oidp, &i, 0, req);
398 	if (error || !req->newptr) {
399 		goto out_locked;
400 	}
401 
402 	if (i < -1 || i >= 60) {
403 		error = EINVAL;
404 		goto out_locked;
405 	}
406 
407 	igmp_gsrdelay.tv_sec = i;
408 
409 out_locked:
410 	IGMP_UNLOCK();
411 	return error;
412 }
413 
414 /*
415  * Expose struct igmp_ifinfo to userland, keyed by ifindex.
416  * For use by ifmcstat(8).
417  *
418  */
419 static int
420 sysctl_igmp_ifinfo SYSCTL_HANDLER_ARGS
421 {
422 #pragma unused(oidp)
423 	int                     *name;
424 	int                      error;
425 	u_int                    namelen;
426 	struct ifnet            *ifp;
427 	struct igmp_ifinfo      *igi;
428 	struct igmp_ifinfo_u    igi_u;
429 
430 	name = (int *)arg1;
431 	namelen = arg2;
432 
433 	if (req->newptr != USER_ADDR_NULL) {
434 		return EPERM;
435 	}
436 
437 	if (namelen != 1) {
438 		return EINVAL;
439 	}
440 
441 	IGMP_LOCK();
442 
443 	if (name[0] <= 0 || name[0] > (u_int)if_index) {
444 		error = ENOENT;
445 		goto out_locked;
446 	}
447 
448 	error = ENOENT;
449 
450 	ifnet_head_lock_shared();
451 	ifp = ifindex2ifnet[name[0]];
452 	ifnet_head_done();
453 	if (ifp == NULL) {
454 		goto out_locked;
455 	}
456 
457 	bzero(&igi_u, sizeof(igi_u));
458 
459 	LIST_FOREACH(igi, &igi_head, igi_link) {
460 		IGI_LOCK(igi);
461 		if (ifp != igi->igi_ifp) {
462 			IGI_UNLOCK(igi);
463 			continue;
464 		}
465 		igi_u.igi_ifindex = igi->igi_ifp->if_index;
466 		igi_u.igi_version = igi->igi_version;
467 		igi_u.igi_v1_timer = igi->igi_v1_timer;
468 		igi_u.igi_v2_timer = igi->igi_v2_timer;
469 		igi_u.igi_v3_timer = igi->igi_v3_timer;
470 		igi_u.igi_flags = igi->igi_flags;
471 		igi_u.igi_rv = igi->igi_rv;
472 		igi_u.igi_qi = igi->igi_qi;
473 		igi_u.igi_qri = igi->igi_qri;
474 		igi_u.igi_uri = igi->igi_uri;
475 		IGI_UNLOCK(igi);
476 
477 		error = SYSCTL_OUT(req, &igi_u, sizeof(igi_u));
478 		break;
479 	}
480 
481 out_locked:
482 	IGMP_UNLOCK();
483 	return error;
484 }
485 
486 /*
487  * Dispatch an entire queue of pending packet chains
488  *
489  * Must not be called with inm_lock held.
490  */
491 static void
igmp_dispatch_queue(struct igmp_ifinfo * igi,struct ifqueue * ifq,int limit,const int loop)492 igmp_dispatch_queue(struct igmp_ifinfo *igi, struct ifqueue *ifq, int limit,
493     const int loop)
494 {
495 	struct mbuf *m;
496 	struct ip *ip;
497 
498 	if (igi != NULL) {
499 		IGI_LOCK_ASSERT_HELD(igi);
500 	}
501 
502 	for (;;) {
503 		IF_DEQUEUE(ifq, m);
504 		if (m == NULL) {
505 			break;
506 		}
507 		IGMP_PRINTF(("%s: dispatch 0x%llx from 0x%llx\n", __func__,
508 		    (uint64_t)VM_KERNEL_ADDRPERM(ifq),
509 		    (uint64_t)VM_KERNEL_ADDRPERM(m)));
510 		ip = mtod(m, struct ip *);
511 		if (loop) {
512 			m->m_flags |= M_IGMP_LOOP;
513 		}
514 		if (igi != NULL) {
515 			IGI_UNLOCK(igi);
516 		}
517 		igmp_sendpkt(m);
518 		if (igi != NULL) {
519 			IGI_LOCK(igi);
520 		}
521 		if (--limit == 0) {
522 			break;
523 		}
524 	}
525 
526 	if (igi != NULL) {
527 		IGI_LOCK_ASSERT_HELD(igi);
528 	}
529 }
530 
531 /*
532  * Filter outgoing IGMP report state by group.
533  *
534  * Reports are ALWAYS suppressed for ALL-HOSTS (224.0.0.1).
535  * If the net.inet.igmp.sendlocal sysctl is 0, then IGMP reports are
536  * disabled for all groups in the 224.0.0.0/24 link-local scope. However,
537  * this may break certain IGMP snooping switches which rely on the old
538  * report behaviour.
539  *
540  * Return zero if the given group is one for which IGMP reports
541  * should be suppressed, or non-zero if reports should be issued.
542  */
543 
544 static __inline__
545 int
igmp_isgroupreported(const struct in_addr addr)546 igmp_isgroupreported(const struct in_addr addr)
547 {
548 	if (in_allhosts(addr) ||
549 	    ((!igmp_sendlocal && IN_LOCAL_GROUP(ntohl(addr.s_addr))))) {
550 		return 0;
551 	}
552 
553 	return 1;
554 }
555 
556 /*
557  * Construct a Router Alert option to use in outgoing packets.
558  */
559 static struct mbuf *
igmp_ra_alloc(void)560 igmp_ra_alloc(void)
561 {
562 	struct mbuf     *m;
563 	struct ipoption *p;
564 
565 	MGET(m, M_WAITOK, MT_DATA);
566 	p = mtod(m, struct ipoption *);
567 	p->ipopt_dst.s_addr = INADDR_ANY;
568 	p->ipopt_list[0] = (char)IPOPT_RA;      /* Router Alert Option */
569 	p->ipopt_list[1] = 0x04;        /* 4 bytes long */
570 	p->ipopt_list[2] = IPOPT_EOL;   /* End of IP option list */
571 	p->ipopt_list[3] = 0x00;        /* pad byte */
572 	m->m_len = sizeof(p->ipopt_dst) + p->ipopt_list[1];
573 
574 	return m;
575 }
576 
577 /*
578  * Attach IGMP when PF_INET is attached to an interface.
579  */
580 struct igmp_ifinfo *
igmp_domifattach(struct ifnet * ifp,zalloc_flags_t how)581 igmp_domifattach(struct ifnet *ifp, zalloc_flags_t how)
582 {
583 	struct igmp_ifinfo *igi;
584 
585 	IGMP_PRINTF(("%s: called for ifp 0x%llx(%s)\n",
586 	    __func__, (uint64_t)VM_KERNEL_ADDRPERM(ifp), ifp->if_name));
587 
588 	igi = igi_alloc(how);
589 	if (igi == NULL) {
590 		return NULL;
591 	}
592 
593 	IGMP_LOCK();
594 
595 	IGI_LOCK(igi);
596 	igi_initvar(igi, ifp, 0);
597 	igi->igi_debug |= IFD_ATTACHED;
598 	IGI_ADDREF_LOCKED(igi); /* hold a reference for igi_head */
599 	IGI_ADDREF_LOCKED(igi); /* hold a reference for caller */
600 	IGI_UNLOCK(igi);
601 	ifnet_lock_shared(ifp);
602 	igmp_initsilent(ifp, igi);
603 	ifnet_lock_done(ifp);
604 
605 	LIST_INSERT_HEAD(&igi_head, igi, igi_link);
606 
607 	IGMP_UNLOCK();
608 
609 	IGMP_PRINTF(("%s: allocate igmp_ifinfo for ifp 0x%llx(%s)\n", __func__,
610 	    (uint64_t)VM_KERNEL_ADDRPERM(ifp), ifp->if_name));
611 
612 	return igi;
613 }
614 
615 /*
616  * Attach IGMP when PF_INET is reattached to an interface.  Caller is
617  * expected to have an outstanding reference to the igi.
618  */
619 void
igmp_domifreattach(struct igmp_ifinfo * igi)620 igmp_domifreattach(struct igmp_ifinfo *igi)
621 {
622 	struct ifnet *ifp;
623 
624 	IGMP_LOCK();
625 
626 	IGI_LOCK(igi);
627 	VERIFY(!(igi->igi_debug & IFD_ATTACHED));
628 	ifp = igi->igi_ifp;
629 	VERIFY(ifp != NULL);
630 	igi_initvar(igi, ifp, 1);
631 	igi->igi_debug |= IFD_ATTACHED;
632 	IGI_ADDREF_LOCKED(igi); /* hold a reference for igi_head */
633 	IGI_UNLOCK(igi);
634 	ifnet_lock_shared(ifp);
635 	igmp_initsilent(ifp, igi);
636 	ifnet_lock_done(ifp);
637 
638 	LIST_INSERT_HEAD(&igi_head, igi, igi_link);
639 
640 	IGMP_UNLOCK();
641 
642 	IGMP_PRINTF(("%s: reattached igmp_ifinfo for ifp 0x%llx(%s)\n",
643 	    __func__, (uint64_t)VM_KERNEL_ADDRPERM(ifp), ifp->if_name));
644 }
645 
646 /*
647  * Hook for domifdetach.
648  */
649 void
igmp_domifdetach(struct ifnet * ifp)650 igmp_domifdetach(struct ifnet *ifp)
651 {
652 	SLIST_HEAD(, in_multi) inm_dthead;
653 
654 	SLIST_INIT(&inm_dthead);
655 
656 	IGMP_PRINTF(("%s: called for ifp 0x%llx(%s%d)\n", __func__,
657 	    (uint64_t)VM_KERNEL_ADDRPERM(ifp), ifp->if_name, ifp->if_unit));
658 
659 	IGMP_LOCK();
660 	igi_delete(ifp, (struct igmp_inm_relhead *)&inm_dthead);
661 	IGMP_UNLOCK();
662 
663 	/* Now that we're dropped all locks, release detached records */
664 	IGMP_REMOVE_DETACHED_INM(&inm_dthead);
665 }
666 
667 /*
668  * Called at interface detach time.  Note that we only flush all deferred
669  * responses and record releases; all remaining inm records and their source
670  * entries related to this interface are left intact, in order to handle
671  * the reattach case.
672  */
673 static void
igi_delete(const struct ifnet * ifp,struct igmp_inm_relhead * inm_dthead)674 igi_delete(const struct ifnet *ifp, struct igmp_inm_relhead *inm_dthead)
675 {
676 	struct igmp_ifinfo *igi, *tigi;
677 
678 	IGMP_LOCK_ASSERT_HELD();
679 
680 	LIST_FOREACH_SAFE(igi, &igi_head, igi_link, tigi) {
681 		IGI_LOCK(igi);
682 		if (igi->igi_ifp == ifp) {
683 			/*
684 			 * Free deferred General Query responses.
685 			 */
686 			IF_DRAIN(&igi->igi_gq);
687 			IF_DRAIN(&igi->igi_v2q);
688 			igmp_flush_relq(igi, inm_dthead);
689 			VERIFY(SLIST_EMPTY(&igi->igi_relinmhead));
690 			igi->igi_debug &= ~IFD_ATTACHED;
691 			IGI_UNLOCK(igi);
692 
693 			LIST_REMOVE(igi, igi_link);
694 			IGI_REMREF(igi); /* release igi_head reference */
695 			return;
696 		}
697 		IGI_UNLOCK(igi);
698 	}
699 	panic("%s: igmp_ifinfo not found for ifp %p(%s)", __func__,
700 	    ifp, ifp->if_xname);
701 }
702 
703 __private_extern__ void
igmp_initsilent(struct ifnet * ifp,struct igmp_ifinfo * igi)704 igmp_initsilent(struct ifnet *ifp, struct igmp_ifinfo *igi)
705 {
706 	ifnet_lock_assert(ifp, IFNET_LCK_ASSERT_OWNED);
707 
708 	IGI_LOCK_ASSERT_NOTHELD(igi);
709 	IGI_LOCK(igi);
710 	if (!(ifp->if_flags & IFF_MULTICAST)) {
711 		igi->igi_flags |= IGIF_SILENT;
712 	} else {
713 		igi->igi_flags &= ~IGIF_SILENT;
714 	}
715 	IGI_UNLOCK(igi);
716 }
717 
718 static void
igi_initvar(struct igmp_ifinfo * igi,struct ifnet * ifp,int reattach)719 igi_initvar(struct igmp_ifinfo *igi, struct ifnet *ifp, int reattach)
720 {
721 	IGI_LOCK_ASSERT_HELD(igi);
722 
723 	igi->igi_ifp = ifp;
724 	igi->igi_version = igmp_default_version;
725 	igi->igi_flags = 0;
726 	igi->igi_rv = IGMP_RV_INIT;
727 	igi->igi_qi = IGMP_QI_INIT;
728 	igi->igi_qri = IGMP_QRI_INIT;
729 	igi->igi_uri = IGMP_URI_INIT;
730 
731 	if (!reattach) {
732 		SLIST_INIT(&igi->igi_relinmhead);
733 	}
734 
735 	/*
736 	 * Responses to general queries are subject to bounds.
737 	 */
738 	igi->igi_gq.ifq_maxlen =  IGMP_MAX_RESPONSE_PACKETS;
739 	igi->igi_v2q.ifq_maxlen = IGMP_MAX_RESPONSE_PACKETS;
740 }
741 
742 static struct igmp_ifinfo *
igi_alloc(zalloc_flags_t how)743 igi_alloc(zalloc_flags_t how)
744 {
745 	struct igmp_ifinfo *igi = zalloc_flags(igi_zone, how | Z_ZERO);
746 	if (igi != NULL) {
747 		lck_mtx_init(&igi->igi_lock, &igmp_mtx_grp, &igmp_mtx_attr);
748 		igi->igi_debug |= IFD_ALLOC;
749 	}
750 	return igi;
751 }
752 
753 static void
igi_free(struct igmp_ifinfo * igi)754 igi_free(struct igmp_ifinfo *igi)
755 {
756 	IGI_LOCK(igi);
757 	if (igi->igi_debug & IFD_ATTACHED) {
758 		panic("%s: attached igi=%p is being freed", __func__, igi);
759 		/* NOTREACHED */
760 	} else if (igi->igi_ifp != NULL) {
761 		panic("%s: ifp not NULL for igi=%p", __func__, igi);
762 		/* NOTREACHED */
763 	} else if (!(igi->igi_debug & IFD_ALLOC)) {
764 		panic("%s: igi %p cannot be freed", __func__, igi);
765 		/* NOTREACHED */
766 	} else if (igi->igi_refcnt != 0) {
767 		panic("%s: non-zero refcnt igi=%p", __func__, igi);
768 		/* NOTREACHED */
769 	}
770 	igi->igi_debug &= ~IFD_ALLOC;
771 	IGI_UNLOCK(igi);
772 
773 	lck_mtx_destroy(&igi->igi_lock, &igmp_mtx_grp);
774 	zfree(igi_zone, igi);
775 }
776 
777 void
igi_addref(struct igmp_ifinfo * igi,int locked)778 igi_addref(struct igmp_ifinfo *igi, int locked)
779 {
780 	if (!locked) {
781 		IGI_LOCK_SPIN(igi);
782 	} else {
783 		IGI_LOCK_ASSERT_HELD(igi);
784 	}
785 
786 	if (++igi->igi_refcnt == 0) {
787 		panic("%s: igi=%p wraparound refcnt", __func__, igi);
788 		/* NOTREACHED */
789 	}
790 	if (!locked) {
791 		IGI_UNLOCK(igi);
792 	}
793 }
794 
795 void
igi_remref(struct igmp_ifinfo * igi)796 igi_remref(struct igmp_ifinfo *igi)
797 {
798 	SLIST_HEAD(, in_multi) inm_dthead;
799 	struct ifnet *ifp;
800 
801 	IGI_LOCK_SPIN(igi);
802 
803 	if (igi->igi_refcnt == 0) {
804 		panic("%s: igi=%p negative refcnt", __func__, igi);
805 		/* NOTREACHED */
806 	}
807 
808 	--igi->igi_refcnt;
809 	if (igi->igi_refcnt > 0) {
810 		IGI_UNLOCK(igi);
811 		return;
812 	}
813 
814 	ifp = igi->igi_ifp;
815 	igi->igi_ifp = NULL;
816 	IF_DRAIN(&igi->igi_gq);
817 	IF_DRAIN(&igi->igi_v2q);
818 	SLIST_INIT(&inm_dthead);
819 	igmp_flush_relq(igi, (struct igmp_inm_relhead *)&inm_dthead);
820 	VERIFY(SLIST_EMPTY(&igi->igi_relinmhead));
821 	IGI_UNLOCK(igi);
822 
823 	/* Now that we're dropped all locks, release detached records */
824 	IGMP_REMOVE_DETACHED_INM(&inm_dthead);
825 
826 	IGMP_PRINTF(("%s: freeing igmp_ifinfo for ifp 0x%llx(%s)\n",
827 	    __func__, (uint64_t)VM_KERNEL_ADDRPERM(ifp), if_name(ifp)));
828 
829 	igi_free(igi);
830 }
831 
832 /*
833  * Process a received IGMPv1 query.
834  * Return non-zero if the message should be dropped.
835  */
836 static int
igmp_input_v1_query(struct ifnet * ifp,const struct ip * ip,const struct igmp * igmp)837 igmp_input_v1_query(struct ifnet *ifp, const struct ip *ip,
838     const struct igmp *igmp)
839 {
840 	struct igmp_ifinfo      *igi;
841 	struct in_multi         *inm;
842 	struct in_multistep     step;
843 	struct igmp_tparams     itp = { .qpt = 0, .it = 0, .cst = 0, .sct = 0 };
844 
845 	IGMP_LOCK_ASSERT_NOTHELD();
846 
847 	/*
848 	 * IGMPv1 Host Membership Queries SHOULD always be addressed to
849 	 * 224.0.0.1. They are always treated as General Queries.
850 	 * igmp_group is always ignored. Do not drop it as a userland
851 	 * daemon may wish to see it.
852 	 */
853 	if (!in_allhosts(ip->ip_dst) || !in_nullhost(igmp->igmp_group)) {
854 		IGMPSTAT_INC(igps_rcv_badqueries);
855 		OIGMPSTAT_INC(igps_rcv_badqueries);
856 		goto done;
857 	}
858 	IGMPSTAT_INC(igps_rcv_gen_queries);
859 
860 	igi = IGMP_IFINFO(ifp);
861 	VERIFY(igi != NULL);
862 
863 	IGI_LOCK(igi);
864 	if (igi->igi_flags & IGIF_LOOPBACK) {
865 		IGMP_PRINTF(("%s: ignore v1 query on IGIF_LOOPBACK "
866 		    "ifp 0x%llx(%s)\n", __func__,
867 		    (uint64_t)VM_KERNEL_ADDRPERM(ifp), if_name(ifp)));
868 		IGI_UNLOCK(igi);
869 		goto done;
870 	}
871 	/*
872 	 * Switch to IGMPv1 host compatibility mode.
873 	 */
874 	itp.qpt = igmp_set_version(igi, IGMP_VERSION_1);
875 	IGI_UNLOCK(igi);
876 
877 	IGMP_PRINTF(("%s: process v1 query on ifp 0x%llx(%s)\n", __func__,
878 	    (uint64_t)VM_KERNEL_ADDRPERM(ifp), if_name(ifp)));
879 
880 	/*
881 	 * Start the timers in all of our group records
882 	 * for the interface on which the query arrived,
883 	 * except those which are already running.
884 	 */
885 	in_multihead_lock_shared();
886 	IN_FIRST_MULTI(step, inm);
887 	while (inm != NULL) {
888 		INM_LOCK(inm);
889 		if (inm->inm_ifp != ifp || inm->inm_timer != 0) {
890 			goto next;
891 		}
892 
893 		switch (inm->inm_state) {
894 		case IGMP_NOT_MEMBER:
895 		case IGMP_SILENT_MEMBER:
896 			break;
897 		case IGMP_G_QUERY_PENDING_MEMBER:
898 		case IGMP_SG_QUERY_PENDING_MEMBER:
899 		case IGMP_REPORTING_MEMBER:
900 		case IGMP_IDLE_MEMBER:
901 		case IGMP_LAZY_MEMBER:
902 		case IGMP_SLEEPING_MEMBER:
903 		case IGMP_AWAKENING_MEMBER:
904 			inm->inm_state = IGMP_REPORTING_MEMBER;
905 			inm->inm_timer = IGMP_RANDOM_DELAY(IGMP_V1V2_MAX_RI);
906 			itp.cst = 1;
907 			break;
908 		case IGMP_LEAVING_MEMBER:
909 			break;
910 		}
911 next:
912 		INM_UNLOCK(inm);
913 		IN_NEXT_MULTI(step, inm);
914 	}
915 	in_multihead_lock_done();
916 done:
917 	igmp_set_timeout(&itp);
918 
919 	return 0;
920 }
921 
922 /*
923  * Process a received IGMPv2 general or group-specific query.
924  */
925 static int
igmp_input_v2_query(struct ifnet * ifp,const struct ip * ip,const struct igmp * igmp)926 igmp_input_v2_query(struct ifnet *ifp, const struct ip *ip,
927     const struct igmp *igmp)
928 {
929 	struct igmp_ifinfo      *igi;
930 	struct in_multi         *inm;
931 	int                      is_general_query;
932 	uint16_t                 timer;
933 	struct igmp_tparams      itp = { .qpt = 0, .it = 0, .cst = 0, .sct = 0 };
934 
935 	IGMP_LOCK_ASSERT_NOTHELD();
936 
937 	is_general_query = 0;
938 
939 	/*
940 	 * Validate address fields upfront.
941 	 */
942 	if (in_nullhost(igmp->igmp_group)) {
943 		/*
944 		 * IGMPv2 General Query.
945 		 * If this was not sent to the all-hosts group, ignore it.
946 		 */
947 		if (!in_allhosts(ip->ip_dst)) {
948 			goto done;
949 		}
950 		IGMPSTAT_INC(igps_rcv_gen_queries);
951 		is_general_query = 1;
952 	} else {
953 		/* IGMPv2 Group-Specific Query. */
954 		IGMPSTAT_INC(igps_rcv_group_queries);
955 	}
956 
957 	igi = IGMP_IFINFO(ifp);
958 	VERIFY(igi != NULL);
959 
960 	IGI_LOCK(igi);
961 	if (igi->igi_flags & IGIF_LOOPBACK) {
962 		IGMP_PRINTF(("%s: ignore v2 query on IGIF_LOOPBACK "
963 		    "ifp 0x%llx(%s)\n", __func__,
964 		    (uint64_t)VM_KERNEL_ADDRPERM(ifp), if_name(ifp)));
965 		IGI_UNLOCK(igi);
966 		goto done;
967 	}
968 	/*
969 	 * Ignore v2 query if in v1 Compatibility Mode.
970 	 */
971 	if (igi->igi_version == IGMP_VERSION_1) {
972 		IGI_UNLOCK(igi);
973 		goto done;
974 	}
975 	itp.qpt = igmp_set_version(igi, IGMP_VERSION_2);
976 	IGI_UNLOCK(igi);
977 
978 	timer = igmp->igmp_code / IGMP_TIMER_SCALE;
979 	if (timer == 0) {
980 		timer = 1;
981 	}
982 
983 	if (is_general_query) {
984 		struct in_multistep step;
985 
986 		IGMP_PRINTF(("%s: process v2 general query on ifp 0x%llx(%s)\n",
987 		    __func__, (uint64_t)VM_KERNEL_ADDRPERM(ifp), if_name(ifp)));
988 		/*
989 		 * For each reporting group joined on this
990 		 * interface, kick the report timer.
991 		 */
992 		in_multihead_lock_shared();
993 		IN_FIRST_MULTI(step, inm);
994 		while (inm != NULL) {
995 			INM_LOCK(inm);
996 			if (inm->inm_ifp == ifp) {
997 				itp.cst += igmp_v2_update_group(inm, timer);
998 			}
999 			INM_UNLOCK(inm);
1000 			IN_NEXT_MULTI(step, inm);
1001 		}
1002 		in_multihead_lock_done();
1003 	} else {
1004 		/*
1005 		 * Group-specific IGMPv2 query, we need only
1006 		 * look up the single group to process it.
1007 		 */
1008 		in_multihead_lock_shared();
1009 		IN_LOOKUP_MULTI(&igmp->igmp_group, ifp, inm);
1010 		in_multihead_lock_done();
1011 		if (inm != NULL) {
1012 			INM_LOCK(inm);
1013 			IGMP_INET_PRINTF(igmp->igmp_group,
1014 			    ("process v2 query %s on ifp 0x%llx(%s)\n",
1015 			    _igmp_inet_buf,
1016 			    (uint64_t)VM_KERNEL_ADDRPERM(ifp), if_name(ifp)));
1017 			itp.cst = igmp_v2_update_group(inm, timer);
1018 			INM_UNLOCK(inm);
1019 			INM_REMREF(inm); /* from IN_LOOKUP_MULTI */
1020 		}
1021 	}
1022 done:
1023 	igmp_set_timeout(&itp);
1024 
1025 	return 0;
1026 }
1027 
1028 /*
1029  * Update the report timer on a group in response to an IGMPv2 query.
1030  *
1031  * If we are becoming the reporting member for this group, start the timer.
1032  * If we already are the reporting member for this group, and timer is
1033  * below the threshold, reset it.
1034  *
1035  * We may be updating the group for the first time since we switched
1036  * to IGMPv3. If we are, then we must clear any recorded source lists,
1037  * and transition to REPORTING state; the group timer is overloaded
1038  * for group and group-source query responses.
1039  *
1040  * Unlike IGMPv3, the delay per group should be jittered
1041  * to avoid bursts of IGMPv2 reports.
1042  */
1043 static uint32_t
igmp_v2_update_group(struct in_multi * inm,const int timer)1044 igmp_v2_update_group(struct in_multi *inm, const int timer)
1045 {
1046 	IGMP_INET_PRINTF(inm->inm_addr, ("%s: %s/%s timer=%d\n",
1047 	    __func__, _igmp_inet_buf, if_name(inm->inm_ifp),
1048 	    timer));
1049 
1050 	INM_LOCK_ASSERT_HELD(inm);
1051 
1052 	switch (inm->inm_state) {
1053 	case IGMP_NOT_MEMBER:
1054 	case IGMP_SILENT_MEMBER:
1055 		break;
1056 	case IGMP_REPORTING_MEMBER:
1057 		if (inm->inm_timer != 0 &&
1058 		    inm->inm_timer <= timer) {
1059 			IGMP_PRINTF(("%s: REPORTING and timer running, "
1060 			    "skipping.\n", __func__));
1061 			break;
1062 		}
1063 		OS_FALLTHROUGH;
1064 	case IGMP_SG_QUERY_PENDING_MEMBER:
1065 	case IGMP_G_QUERY_PENDING_MEMBER:
1066 	case IGMP_IDLE_MEMBER:
1067 	case IGMP_LAZY_MEMBER:
1068 	case IGMP_AWAKENING_MEMBER:
1069 		IGMP_PRINTF(("%s: ->REPORTING\n", __func__));
1070 		inm->inm_state = IGMP_REPORTING_MEMBER;
1071 		inm->inm_timer = IGMP_RANDOM_DELAY(timer);
1072 		break;
1073 	case IGMP_SLEEPING_MEMBER:
1074 		IGMP_PRINTF(("%s: ->AWAKENING\n", __func__));
1075 		inm->inm_state = IGMP_AWAKENING_MEMBER;
1076 		break;
1077 	case IGMP_LEAVING_MEMBER:
1078 		break;
1079 	}
1080 
1081 	return inm->inm_timer;
1082 }
1083 
1084 /*
1085  * Process a received IGMPv3 general, group-specific or
1086  * group-and-source-specific query.
1087  * Assumes m has already been pulled up to the full IGMP message length.
1088  * Return 0 if successful, otherwise an appropriate error code is returned.
1089  */
1090 static int
igmp_input_v3_query(struct ifnet * ifp,const struct ip * ip,struct igmpv3 * igmpv3)1091 igmp_input_v3_query(struct ifnet *ifp, const struct ip *ip,
1092     /*const*/ struct igmpv3 *igmpv3)
1093 {
1094 	struct igmp_ifinfo      *igi;
1095 	struct in_multi         *inm;
1096 	int                      is_general_query;
1097 	uint32_t                 maxresp, nsrc, qqi;
1098 	uint32_t                 timer;
1099 	uint8_t                  qrv;
1100 	struct igmp_tparams      itp = { .qpt = 0, .it = 0, .cst = 0, .sct = 0 };
1101 
1102 	IGMP_LOCK_ASSERT_NOTHELD();
1103 
1104 	is_general_query = 0;
1105 
1106 	IGMP_PRINTF(("%s: process v3 query on ifp 0x%llx(%s)\n", __func__,
1107 	    (uint64_t)VM_KERNEL_ADDRPERM(ifp), if_name(ifp)));
1108 
1109 	maxresp = igmpv3->igmp_code;    /* in 1/10ths of a second */
1110 	if (maxresp >= 128) {
1111 		maxresp = IGMP_MANT(igmpv3->igmp_code) <<
1112 		    (IGMP_EXP(igmpv3->igmp_code) + 3);
1113 	}
1114 
1115 	/*
1116 	 * Robustness must never be less than 2 for on-wire IGMPv3.
1117 	 * FUTURE: Check if ifp has IGIF_LOOPBACK set, as we will make
1118 	 * an exception for interfaces whose IGMPv3 state changes
1119 	 * are redirected to loopback (e.g. MANET).
1120 	 */
1121 	qrv = IGMP_QRV(igmpv3->igmp_misc);
1122 	if (qrv < 2) {
1123 		IGMP_PRINTF(("%s: clamping qrv %d to %d\n", __func__,
1124 		    qrv, IGMP_RV_INIT));
1125 		qrv = IGMP_RV_INIT;
1126 	}
1127 
1128 	qqi = igmpv3->igmp_qqi;
1129 	if (qqi >= 128) {
1130 		qqi = IGMP_MANT(igmpv3->igmp_qqi) <<
1131 		    (IGMP_EXP(igmpv3->igmp_qqi) + 3);
1132 	}
1133 
1134 	timer = maxresp / IGMP_TIMER_SCALE;
1135 	if (timer == 0) {
1136 		timer = 1;
1137 	}
1138 
1139 	nsrc = ntohs(igmpv3->igmp_numsrc);
1140 
1141 	/*
1142 	 * Validate address fields and versions upfront before
1143 	 * accepting v3 query.
1144 	 */
1145 	if (in_nullhost(igmpv3->igmp_group)) {
1146 		/*
1147 		 * IGMPv3 General Query.
1148 		 *
1149 		 * General Queries SHOULD be directed to 224.0.0.1.
1150 		 * A general query with a source list has undefined
1151 		 * behaviour; discard it.
1152 		 */
1153 		IGMPSTAT_INC(igps_rcv_gen_queries);
1154 		if (!in_allhosts(ip->ip_dst) || nsrc > 0) {
1155 			IGMPSTAT_INC(igps_rcv_badqueries);
1156 			OIGMPSTAT_INC(igps_rcv_badqueries);
1157 			goto done;
1158 		}
1159 		is_general_query = 1;
1160 	} else {
1161 		/* Group or group-source specific query. */
1162 		if (nsrc == 0) {
1163 			IGMPSTAT_INC(igps_rcv_group_queries);
1164 		} else {
1165 			IGMPSTAT_INC(igps_rcv_gsr_queries);
1166 		}
1167 	}
1168 
1169 	igi = IGMP_IFINFO(ifp);
1170 	VERIFY(igi != NULL);
1171 
1172 	IGI_LOCK(igi);
1173 	if (igi->igi_flags & IGIF_LOOPBACK) {
1174 		IGMP_PRINTF(("%s: ignore v3 query on IGIF_LOOPBACK "
1175 		    "ifp 0x%llx(%s)\n", __func__,
1176 		    (uint64_t)VM_KERNEL_ADDRPERM(ifp), if_name(ifp)));
1177 		IGI_UNLOCK(igi);
1178 		goto done;
1179 	}
1180 
1181 	/*
1182 	 * Discard the v3 query if we're in Compatibility Mode.
1183 	 * The RFC is not obviously worded that hosts need to stay in
1184 	 * compatibility mode until the Old Version Querier Present
1185 	 * timer expires.
1186 	 */
1187 	if (igi->igi_version != IGMP_VERSION_3) {
1188 		IGMP_PRINTF(("%s: ignore v3 query in v%d mode on "
1189 		    "ifp 0x%llx(%s)\n", __func__, igi->igi_version,
1190 		    (uint64_t)VM_KERNEL_ADDRPERM(ifp), if_name(ifp)));
1191 		IGI_UNLOCK(igi);
1192 		goto done;
1193 	}
1194 
1195 	itp.qpt = igmp_set_version(igi, IGMP_VERSION_3);
1196 	igi->igi_rv = qrv;
1197 	igi->igi_qi = qqi;
1198 	igi->igi_qri = MAX(timer, IGMP_QRI_MIN);
1199 
1200 	IGMP_PRINTF(("%s: qrv %d qi %d qri %d\n", __func__, igi->igi_rv,
1201 	    igi->igi_qi, igi->igi_qri));
1202 
1203 	if (is_general_query) {
1204 		/*
1205 		 * Schedule a current-state report on this ifp for
1206 		 * all groups, possibly containing source lists.
1207 		 * If there is a pending General Query response
1208 		 * scheduled earlier than the selected delay, do
1209 		 * not schedule any other reports.
1210 		 * Otherwise, reset the interface timer.
1211 		 */
1212 		IGMP_PRINTF(("%s: process v3 general query on ifp 0x%llx(%s)\n",
1213 		    __func__, (uint64_t)VM_KERNEL_ADDRPERM(ifp), if_name(ifp)));
1214 		if (igi->igi_v3_timer == 0 || igi->igi_v3_timer >= timer) {
1215 			itp.it = igi->igi_v3_timer = IGMP_RANDOM_DELAY(timer);
1216 		}
1217 		IGI_UNLOCK(igi);
1218 	} else {
1219 		IGI_UNLOCK(igi);
1220 		/*
1221 		 * Group-source-specific queries are throttled on
1222 		 * a per-group basis to defeat denial-of-service attempts.
1223 		 * Queries for groups we are not a member of on this
1224 		 * link are simply ignored.
1225 		 */
1226 		in_multihead_lock_shared();
1227 		IN_LOOKUP_MULTI(&igmpv3->igmp_group, ifp, inm);
1228 		in_multihead_lock_done();
1229 		if (inm == NULL) {
1230 			goto done;
1231 		}
1232 
1233 		INM_LOCK(inm);
1234 		if (nsrc > 0) {
1235 			if (!ratecheck(&inm->inm_lastgsrtv,
1236 			    &igmp_gsrdelay)) {
1237 				IGMP_PRINTF(("%s: GS query throttled.\n",
1238 				    __func__));
1239 				IGMPSTAT_INC(igps_drop_gsr_queries);
1240 				INM_UNLOCK(inm);
1241 				INM_REMREF(inm); /* from IN_LOOKUP_MULTI */
1242 				goto done;
1243 			}
1244 		}
1245 		IGMP_INET_PRINTF(igmpv3->igmp_group,
1246 		    ("process v3 %s query on ifp 0x%llx(%s)\n", _igmp_inet_buf,
1247 		    (uint64_t)VM_KERNEL_ADDRPERM(ifp), if_name(ifp)));
1248 		/*
1249 		 * If there is a pending General Query response
1250 		 * scheduled sooner than the selected delay, no
1251 		 * further report need be scheduled.
1252 		 * Otherwise, prepare to respond to the
1253 		 * group-specific or group-and-source query.
1254 		 */
1255 		IGI_LOCK(igi);
1256 		itp.it = igi->igi_v3_timer;
1257 		IGI_UNLOCK(igi);
1258 		if (itp.it == 0 || itp.it >= timer) {
1259 			(void) igmp_input_v3_group_query(inm, timer, igmpv3);
1260 			itp.cst = inm->inm_timer;
1261 		}
1262 		INM_UNLOCK(inm);
1263 		INM_REMREF(inm); /* from IN_LOOKUP_MULTI */
1264 	}
1265 done:
1266 	if (itp.it > 0) {
1267 		IGMP_PRINTF(("%s: v3 general query response scheduled in "
1268 		    "T+%d seconds on ifp 0x%llx(%s)\n", __func__, itp.it,
1269 		    (uint64_t)VM_KERNEL_ADDRPERM(ifp), if_name(ifp)));
1270 	}
1271 	igmp_set_timeout(&itp);
1272 
1273 	return 0;
1274 }
1275 
1276 /*
1277  * Process a recieved IGMPv3 group-specific or group-and-source-specific
1278  * query.
1279  * Return <0 if any error occured. Currently this is ignored.
1280  */
1281 static int
igmp_input_v3_group_query(struct in_multi * inm,int timer,struct igmpv3 * igmpv3)1282 igmp_input_v3_group_query(struct in_multi *inm,
1283     int timer, /*const*/ struct igmpv3 *igmpv3)
1284 {
1285 	int                      retval;
1286 	uint16_t                 nsrc;
1287 
1288 	INM_LOCK_ASSERT_HELD(inm);
1289 
1290 	retval = 0;
1291 
1292 	switch (inm->inm_state) {
1293 	case IGMP_NOT_MEMBER:
1294 	case IGMP_SILENT_MEMBER:
1295 	case IGMP_SLEEPING_MEMBER:
1296 	case IGMP_LAZY_MEMBER:
1297 	case IGMP_AWAKENING_MEMBER:
1298 	case IGMP_IDLE_MEMBER:
1299 	case IGMP_LEAVING_MEMBER:
1300 		return retval;
1301 	case IGMP_REPORTING_MEMBER:
1302 	case IGMP_G_QUERY_PENDING_MEMBER:
1303 	case IGMP_SG_QUERY_PENDING_MEMBER:
1304 		break;
1305 	}
1306 
1307 	nsrc = ntohs(igmpv3->igmp_numsrc);
1308 
1309 	/*
1310 	 * Deal with group-specific queries upfront.
1311 	 * If any group query is already pending, purge any recorded
1312 	 * source-list state if it exists, and schedule a query response
1313 	 * for this group-specific query.
1314 	 */
1315 	if (nsrc == 0) {
1316 		if (inm->inm_state == IGMP_G_QUERY_PENDING_MEMBER ||
1317 		    inm->inm_state == IGMP_SG_QUERY_PENDING_MEMBER) {
1318 			inm_clear_recorded(inm);
1319 			timer = min(inm->inm_timer, timer);
1320 		}
1321 		inm->inm_state = IGMP_G_QUERY_PENDING_MEMBER;
1322 		inm->inm_timer = IGMP_RANDOM_DELAY(timer);
1323 		return retval;
1324 	}
1325 
1326 	/*
1327 	 * Deal with the case where a group-and-source-specific query has
1328 	 * been received but a group-specific query is already pending.
1329 	 */
1330 	if (inm->inm_state == IGMP_G_QUERY_PENDING_MEMBER) {
1331 		timer = min(inm->inm_timer, timer);
1332 		inm->inm_timer = IGMP_RANDOM_DELAY(timer);
1333 		return retval;
1334 	}
1335 
1336 	/*
1337 	 * Finally, deal with the case where a group-and-source-specific
1338 	 * query has been received, where a response to a previous g-s-r
1339 	 * query exists, or none exists.
1340 	 * In this case, we need to parse the source-list which the Querier
1341 	 * has provided us with and check if we have any source list filter
1342 	 * entries at T1 for these sources. If we do not, there is no need
1343 	 * schedule a report and the query may be dropped.
1344 	 * If we do, we must record them and schedule a current-state
1345 	 * report for those sources.
1346 	 * FIXME: Handling source lists larger than 1 mbuf requires that
1347 	 * we pass the mbuf chain pointer down to this function, and use
1348 	 * m_getptr() to walk the chain.
1349 	 */
1350 	if (inm->inm_nsrc > 0) {
1351 		const struct in_addr    *ap;
1352 		int                      i, nrecorded;
1353 
1354 		ap = (const struct in_addr *)(igmpv3 + 1);
1355 		nrecorded = 0;
1356 		for (i = 0; i < nsrc; i++, ap++) {
1357 			retval = inm_record_source(inm, ap->s_addr);
1358 			if (retval < 0) {
1359 				break;
1360 			}
1361 			nrecorded += retval;
1362 		}
1363 		if (nrecorded > 0) {
1364 			IGMP_PRINTF(("%s: schedule response to SG query\n",
1365 			    __func__));
1366 			inm->inm_state = IGMP_SG_QUERY_PENDING_MEMBER;
1367 			inm->inm_timer = IGMP_RANDOM_DELAY(timer);
1368 		}
1369 	}
1370 
1371 	return retval;
1372 }
1373 
1374 /*
1375  * Process a received IGMPv1 host membership report.
1376  *
1377  * NOTE: 0.0.0.0 workaround breaks const correctness.
1378  */
1379 static int
igmp_input_v1_report(struct ifnet * ifp,struct mbuf * m,struct ip * ip,struct igmp * igmp)1380 igmp_input_v1_report(struct ifnet *ifp, struct mbuf *m, /*const*/ struct ip *ip,
1381     /*const*/ struct igmp *igmp)
1382 {
1383 	struct in_ifaddr *ia;
1384 	struct in_multi *inm;
1385 
1386 	IGMPSTAT_INC(igps_rcv_reports);
1387 	OIGMPSTAT_INC(igps_rcv_reports);
1388 
1389 	if ((ifp->if_flags & IFF_LOOPBACK) ||
1390 	    (m->m_pkthdr.pkt_flags & PKTF_LOOP)) {
1391 		return 0;
1392 	}
1393 
1394 	if (!IN_MULTICAST(ntohl(igmp->igmp_group.s_addr) ||
1395 	    !in_hosteq(igmp->igmp_group, ip->ip_dst))) {
1396 		IGMPSTAT_INC(igps_rcv_badreports);
1397 		OIGMPSTAT_INC(igps_rcv_badreports);
1398 		return EINVAL;
1399 	}
1400 
1401 	/*
1402 	 * RFC 3376, Section 4.2.13, 9.2, 9.3:
1403 	 * Booting clients may use the source address 0.0.0.0. Some
1404 	 * IGMP daemons may not know how to use IP_RECVIF to determine
1405 	 * the interface upon which this message was received.
1406 	 * Replace 0.0.0.0 with the subnet address if told to do so.
1407 	 */
1408 	if (igmp_recvifkludge && in_nullhost(ip->ip_src)) {
1409 		IFP_TO_IA(ifp, ia);
1410 		if (ia != NULL) {
1411 			IFA_LOCK(&ia->ia_ifa);
1412 			ip->ip_src.s_addr = htonl(ia->ia_subnet);
1413 			IFA_UNLOCK(&ia->ia_ifa);
1414 			IFA_REMREF(&ia->ia_ifa);
1415 		}
1416 	}
1417 
1418 	IGMP_INET_PRINTF(igmp->igmp_group,
1419 	    ("process v1 report %s on ifp 0x%llx(%s)\n", _igmp_inet_buf,
1420 	    (uint64_t)VM_KERNEL_ADDRPERM(ifp), if_name(ifp)));
1421 
1422 	/*
1423 	 * IGMPv1 report suppression.
1424 	 * If we are a member of this group, and our membership should be
1425 	 * reported, stop our group timer and transition to the 'lazy' state.
1426 	 */
1427 	in_multihead_lock_shared();
1428 	IN_LOOKUP_MULTI(&igmp->igmp_group, ifp, inm);
1429 	in_multihead_lock_done();
1430 	if (inm != NULL) {
1431 		struct igmp_ifinfo *igi;
1432 
1433 		INM_LOCK(inm);
1434 
1435 		igi = inm->inm_igi;
1436 		VERIFY(igi != NULL);
1437 
1438 		IGMPSTAT_INC(igps_rcv_ourreports);
1439 		OIGMPSTAT_INC(igps_rcv_ourreports);
1440 
1441 		/*
1442 		 * If we are in IGMPv3 host mode, do not allow the
1443 		 * other host's IGMPv1 report to suppress our reports
1444 		 * unless explicitly configured to do so.
1445 		 */
1446 		IGI_LOCK(igi);
1447 		if (igi->igi_version == IGMP_VERSION_3) {
1448 			if (igmp_legacysupp) {
1449 				igmp_v3_suppress_group_record(inm);
1450 			}
1451 			IGI_UNLOCK(igi);
1452 			INM_UNLOCK(inm);
1453 			INM_REMREF(inm); /* from IN_LOOKUP_MULTI */
1454 			return 0;
1455 		}
1456 
1457 		INM_LOCK_ASSERT_HELD(inm);
1458 		inm->inm_timer = 0;
1459 
1460 		switch (inm->inm_state) {
1461 		case IGMP_NOT_MEMBER:
1462 		case IGMP_SILENT_MEMBER:
1463 			break;
1464 		case IGMP_IDLE_MEMBER:
1465 		case IGMP_LAZY_MEMBER:
1466 		case IGMP_AWAKENING_MEMBER:
1467 			IGMP_INET_PRINTF(igmp->igmp_group,
1468 			    ("report suppressed for %s on ifp 0x%llx(%s)\n",
1469 			    _igmp_inet_buf,
1470 			    (uint64_t)VM_KERNEL_ADDRPERM(ifp), if_name(ifp)));
1471 			OS_FALLTHROUGH;
1472 		case IGMP_SLEEPING_MEMBER:
1473 			inm->inm_state = IGMP_SLEEPING_MEMBER;
1474 			break;
1475 		case IGMP_REPORTING_MEMBER:
1476 			IGMP_INET_PRINTF(igmp->igmp_group,
1477 			    ("report suppressed for %s on ifp 0x%llx(%s)\n",
1478 			    _igmp_inet_buf,
1479 			    (uint64_t)VM_KERNEL_ADDRPERM(ifp), if_name(ifp)));
1480 			if (igi->igi_version == IGMP_VERSION_1) {
1481 				inm->inm_state = IGMP_LAZY_MEMBER;
1482 			} else if (igi->igi_version == IGMP_VERSION_2) {
1483 				inm->inm_state = IGMP_SLEEPING_MEMBER;
1484 			}
1485 			break;
1486 		case IGMP_G_QUERY_PENDING_MEMBER:
1487 		case IGMP_SG_QUERY_PENDING_MEMBER:
1488 		case IGMP_LEAVING_MEMBER:
1489 			break;
1490 		}
1491 		IGI_UNLOCK(igi);
1492 		INM_UNLOCK(inm);
1493 		INM_REMREF(inm); /* from IN_LOOKUP_MULTI */
1494 	}
1495 
1496 	return 0;
1497 }
1498 
1499 /*
1500  * Process a received IGMPv2 host membership report.
1501  *
1502  * NOTE: 0.0.0.0 workaround breaks const correctness.
1503  */
1504 static int
igmp_input_v2_report(struct ifnet * ifp,struct mbuf * m,struct ip * ip,struct igmp * igmp)1505 igmp_input_v2_report(struct ifnet *ifp, struct mbuf *m, /*const*/ struct ip *ip,
1506     /*const*/ struct igmp *igmp)
1507 {
1508 	struct in_ifaddr *ia;
1509 	struct in_multi *inm;
1510 
1511 	/*
1512 	 * Make sure we don't hear our own membership report.  Fast
1513 	 * leave requires knowing that we are the only member of a
1514 	 * group.
1515 	 */
1516 	IFP_TO_IA(ifp, ia);
1517 	if (ia != NULL) {
1518 		IFA_LOCK(&ia->ia_ifa);
1519 		if (in_hosteq(ip->ip_src, IA_SIN(ia)->sin_addr)) {
1520 			IFA_UNLOCK(&ia->ia_ifa);
1521 			IFA_REMREF(&ia->ia_ifa);
1522 			return 0;
1523 		}
1524 		IFA_UNLOCK(&ia->ia_ifa);
1525 	}
1526 
1527 	IGMPSTAT_INC(igps_rcv_reports);
1528 	OIGMPSTAT_INC(igps_rcv_reports);
1529 
1530 	if ((ifp->if_flags & IFF_LOOPBACK) ||
1531 	    (m->m_pkthdr.pkt_flags & PKTF_LOOP)) {
1532 		if (ia != NULL) {
1533 			IFA_REMREF(&ia->ia_ifa);
1534 		}
1535 		return 0;
1536 	}
1537 
1538 	if (!IN_MULTICAST(ntohl(igmp->igmp_group.s_addr)) ||
1539 	    !in_hosteq(igmp->igmp_group, ip->ip_dst)) {
1540 		if (ia != NULL) {
1541 			IFA_REMREF(&ia->ia_ifa);
1542 		}
1543 		IGMPSTAT_INC(igps_rcv_badreports);
1544 		OIGMPSTAT_INC(igps_rcv_badreports);
1545 		return EINVAL;
1546 	}
1547 
1548 	/*
1549 	 * RFC 3376, Section 4.2.13, 9.2, 9.3:
1550 	 * Booting clients may use the source address 0.0.0.0. Some
1551 	 * IGMP daemons may not know how to use IP_RECVIF to determine
1552 	 * the interface upon which this message was received.
1553 	 * Replace 0.0.0.0 with the subnet address if told to do so.
1554 	 */
1555 	if (igmp_recvifkludge && in_nullhost(ip->ip_src)) {
1556 		if (ia != NULL) {
1557 			IFA_LOCK(&ia->ia_ifa);
1558 			ip->ip_src.s_addr = htonl(ia->ia_subnet);
1559 			IFA_UNLOCK(&ia->ia_ifa);
1560 		}
1561 	}
1562 	if (ia != NULL) {
1563 		IFA_REMREF(&ia->ia_ifa);
1564 	}
1565 
1566 	IGMP_INET_PRINTF(igmp->igmp_group,
1567 	    ("process v2 report %s on ifp 0x%llx(%s)\n", _igmp_inet_buf,
1568 	    (uint64_t)VM_KERNEL_ADDRPERM(ifp), if_name(ifp)));
1569 
1570 	/*
1571 	 * IGMPv2 report suppression.
1572 	 * If we are a member of this group, and our membership should be
1573 	 * reported, and our group timer is pending or about to be reset,
1574 	 * stop our group timer by transitioning to the 'lazy' state.
1575 	 */
1576 	in_multihead_lock_shared();
1577 	IN_LOOKUP_MULTI(&igmp->igmp_group, ifp, inm);
1578 	in_multihead_lock_done();
1579 	if (inm != NULL) {
1580 		struct igmp_ifinfo *igi;
1581 
1582 		INM_LOCK(inm);
1583 		igi = inm->inm_igi;
1584 		VERIFY(igi != NULL);
1585 
1586 		IGMPSTAT_INC(igps_rcv_ourreports);
1587 		OIGMPSTAT_INC(igps_rcv_ourreports);
1588 
1589 		/*
1590 		 * If we are in IGMPv3 host mode, do not allow the
1591 		 * other host's IGMPv1 report to suppress our reports
1592 		 * unless explicitly configured to do so.
1593 		 */
1594 		IGI_LOCK(igi);
1595 		if (igi->igi_version == IGMP_VERSION_3) {
1596 			if (igmp_legacysupp) {
1597 				igmp_v3_suppress_group_record(inm);
1598 			}
1599 			IGI_UNLOCK(igi);
1600 			INM_UNLOCK(inm);
1601 			INM_REMREF(inm);
1602 			return 0;
1603 		}
1604 
1605 		inm->inm_timer = 0;
1606 
1607 		switch (inm->inm_state) {
1608 		case IGMP_NOT_MEMBER:
1609 		case IGMP_SILENT_MEMBER:
1610 		case IGMP_SLEEPING_MEMBER:
1611 			break;
1612 		case IGMP_REPORTING_MEMBER:
1613 		case IGMP_IDLE_MEMBER:
1614 		case IGMP_AWAKENING_MEMBER:
1615 			IGMP_INET_PRINTF(igmp->igmp_group,
1616 			    ("report suppressed for %s on ifp 0x%llx(%s)\n",
1617 			    _igmp_inet_buf, (uint64_t)VM_KERNEL_ADDRPERM(ifp),
1618 			    if_name(ifp)));
1619 			OS_FALLTHROUGH;
1620 		case IGMP_LAZY_MEMBER:
1621 			inm->inm_state = IGMP_LAZY_MEMBER;
1622 			break;
1623 		case IGMP_G_QUERY_PENDING_MEMBER:
1624 		case IGMP_SG_QUERY_PENDING_MEMBER:
1625 		case IGMP_LEAVING_MEMBER:
1626 			break;
1627 		}
1628 		IGI_UNLOCK(igi);
1629 		INM_UNLOCK(inm);
1630 		INM_REMREF(inm);
1631 	}
1632 
1633 	return 0;
1634 }
1635 
1636 void
igmp_input(struct mbuf * m,int off)1637 igmp_input(struct mbuf *m, int off)
1638 {
1639 	int iphlen;
1640 	struct ifnet *ifp;
1641 	struct igmp *igmp;
1642 	struct ip *ip;
1643 	int igmplen;
1644 	int minlen;
1645 	int queryver;
1646 
1647 	IGMP_PRINTF(("%s: called w/mbuf (0x%llx,%d)\n", __func__,
1648 	    (uint64_t)VM_KERNEL_ADDRPERM(m), off));
1649 
1650 	ifp = m->m_pkthdr.rcvif;
1651 
1652 	IGMPSTAT_INC(igps_rcv_total);
1653 	OIGMPSTAT_INC(igps_rcv_total);
1654 
1655 	/* Expect 32-bit aligned data pointer on strict-align platforms */
1656 	MBUF_STRICT_DATA_ALIGNMENT_CHECK_32(m);
1657 
1658 	ip = mtod(m, struct ip *);
1659 	iphlen = off;
1660 
1661 	/* By now, ip_len no longer contains the length of IP header */
1662 	igmplen = ip->ip_len;
1663 
1664 	/*
1665 	 * Validate lengths.
1666 	 */
1667 	if (igmplen < IGMP_MINLEN) {
1668 		IGMPSTAT_INC(igps_rcv_tooshort);
1669 		OIGMPSTAT_INC(igps_rcv_tooshort);
1670 		m_freem(m);
1671 		return;
1672 	}
1673 
1674 	/*
1675 	 * Always pullup to the minimum size for v1/v2 or v3
1676 	 * to amortize calls to m_pulldown().
1677 	 */
1678 	if (igmplen >= IGMP_V3_QUERY_MINLEN) {
1679 		minlen = IGMP_V3_QUERY_MINLEN;
1680 	} else {
1681 		minlen = IGMP_MINLEN;
1682 	}
1683 
1684 	/* A bit more expensive than M_STRUCT_GET, but ensures alignment */
1685 	M_STRUCT_GET0(igmp, struct igmp *, m, off, minlen);
1686 	if (igmp == NULL) {
1687 		IGMPSTAT_INC(igps_rcv_tooshort);
1688 		OIGMPSTAT_INC(igps_rcv_tooshort);
1689 		return;
1690 	}
1691 	/* N.B.: we assume the packet was correctly aligned in ip_input. */
1692 
1693 	/*
1694 	 * Validate checksum.
1695 	 */
1696 	m->m_data += iphlen;
1697 	m->m_len -= iphlen;
1698 	if (in_cksum(m, igmplen)) {
1699 		IGMPSTAT_INC(igps_rcv_badsum);
1700 		OIGMPSTAT_INC(igps_rcv_badsum);
1701 		m_freem(m);
1702 		return;
1703 	}
1704 	m->m_data -= iphlen;
1705 	m->m_len += iphlen;
1706 
1707 	/*
1708 	 * IGMP control traffic is link-scope, and must have a TTL of 1.
1709 	 * DVMRP traffic (e.g. mrinfo, mtrace) is an exception;
1710 	 * probe packets may come from beyond the LAN.
1711 	 */
1712 	if (igmp->igmp_type != IGMP_DVMRP && ip->ip_ttl != 1) {
1713 		IGMPSTAT_INC(igps_rcv_badttl);
1714 		m_freem(m);
1715 		return;
1716 	}
1717 
1718 	switch (igmp->igmp_type) {
1719 	case IGMP_HOST_MEMBERSHIP_QUERY:
1720 		if (igmplen == IGMP_MINLEN) {
1721 			if (igmp->igmp_code == 0) {
1722 				queryver = IGMP_VERSION_1;
1723 			} else {
1724 				queryver = IGMP_VERSION_2;
1725 			}
1726 		} else if (igmplen >= IGMP_V3_QUERY_MINLEN) {
1727 			queryver = IGMP_VERSION_3;
1728 		} else {
1729 			IGMPSTAT_INC(igps_rcv_tooshort);
1730 			OIGMPSTAT_INC(igps_rcv_tooshort);
1731 			m_freem(m);
1732 			return;
1733 		}
1734 
1735 		OIGMPSTAT_INC(igps_rcv_queries);
1736 
1737 		switch (queryver) {
1738 		case IGMP_VERSION_1:
1739 			IGMPSTAT_INC(igps_rcv_v1v2_queries);
1740 			if (!igmp_v1enable) {
1741 				break;
1742 			}
1743 			if (igmp_input_v1_query(ifp, ip, igmp) != 0) {
1744 				m_freem(m);
1745 				return;
1746 			}
1747 			break;
1748 
1749 		case IGMP_VERSION_2:
1750 			IGMPSTAT_INC(igps_rcv_v1v2_queries);
1751 			if (!igmp_v2enable) {
1752 				break;
1753 			}
1754 			if (igmp_input_v2_query(ifp, ip, igmp) != 0) {
1755 				m_freem(m);
1756 				return;
1757 			}
1758 			break;
1759 
1760 		case IGMP_VERSION_3: {
1761 			struct igmpv3 *igmpv3;
1762 			uint16_t igmpv3len;
1763 			uint16_t srclen;
1764 			int nsrc;
1765 
1766 			IGMPSTAT_INC(igps_rcv_v3_queries);
1767 			igmpv3 = (struct igmpv3 *)igmp;
1768 			/*
1769 			 * Validate length based on source count.
1770 			 */
1771 			nsrc = ntohs(igmpv3->igmp_numsrc);
1772 			/*
1773 			 * The max vaue of nsrc is limited by the
1774 			 * MTU of the network on which the datagram
1775 			 * is received
1776 			 */
1777 			if (nsrc < 0 || nsrc > IGMP_V3_QUERY_MAX_SRCS) {
1778 				IGMPSTAT_INC(igps_rcv_tooshort);
1779 				OIGMPSTAT_INC(igps_rcv_tooshort);
1780 				m_freem(m);
1781 				return;
1782 			}
1783 			srclen = sizeof(struct in_addr) * (uint16_t)nsrc;
1784 			if (igmplen < (IGMP_V3_QUERY_MINLEN + srclen)) {
1785 				IGMPSTAT_INC(igps_rcv_tooshort);
1786 				OIGMPSTAT_INC(igps_rcv_tooshort);
1787 				m_freem(m);
1788 				return;
1789 			}
1790 			igmpv3len = IGMP_V3_QUERY_MINLEN + srclen;
1791 			/*
1792 			 * A bit more expensive than M_STRUCT_GET,
1793 			 * but ensures alignment.
1794 			 */
1795 			M_STRUCT_GET0(igmpv3, struct igmpv3 *, m,
1796 			    off, igmpv3len);
1797 			if (igmpv3 == NULL) {
1798 				IGMPSTAT_INC(igps_rcv_tooshort);
1799 				OIGMPSTAT_INC(igps_rcv_tooshort);
1800 				return;
1801 			}
1802 			/*
1803 			 * N.B.: we assume the packet was correctly
1804 			 * aligned in ip_input.
1805 			 */
1806 			if (igmp_input_v3_query(ifp, ip, igmpv3) != 0) {
1807 				m_freem(m);
1808 				return;
1809 			}
1810 		}
1811 		break;
1812 		}
1813 		break;
1814 
1815 	case IGMP_v1_HOST_MEMBERSHIP_REPORT:
1816 		if (!igmp_v1enable) {
1817 			break;
1818 		}
1819 		if (igmp_input_v1_report(ifp, m, ip, igmp) != 0) {
1820 			m_freem(m);
1821 			return;
1822 		}
1823 		break;
1824 
1825 	case IGMP_v2_HOST_MEMBERSHIP_REPORT:
1826 		if (!igmp_v2enable) {
1827 			break;
1828 		}
1829 		if (!ip_checkrouteralert(m)) {
1830 			IGMPSTAT_INC(igps_rcv_nora);
1831 		}
1832 		if (igmp_input_v2_report(ifp, m, ip, igmp) != 0) {
1833 			m_freem(m);
1834 			return;
1835 		}
1836 		break;
1837 
1838 	case IGMP_v3_HOST_MEMBERSHIP_REPORT:
1839 		/*
1840 		 * Hosts do not need to process IGMPv3 membership reports,
1841 		 * as report suppression is no longer required.
1842 		 */
1843 		if (!ip_checkrouteralert(m)) {
1844 			IGMPSTAT_INC(igps_rcv_nora);
1845 		}
1846 		break;
1847 
1848 	default:
1849 		break;
1850 	}
1851 
1852 	IGMP_LOCK_ASSERT_NOTHELD();
1853 	/*
1854 	 * Pass all valid IGMP packets up to any process(es) listening on a
1855 	 * raw IGMP socket.
1856 	 */
1857 	rip_input(m, off);
1858 }
1859 
1860 /*
1861  * Schedule IGMP timer based on various parameters; caller must ensure that
1862  * lock ordering is maintained as this routine acquires IGMP global lock.
1863  */
1864 void
igmp_set_timeout(struct igmp_tparams * itp)1865 igmp_set_timeout(struct igmp_tparams *itp)
1866 {
1867 	IGMP_LOCK_ASSERT_NOTHELD();
1868 	VERIFY(itp != NULL);
1869 
1870 	if (itp->qpt != 0 || itp->it != 0 || itp->cst != 0 || itp->sct != 0) {
1871 		IGMP_LOCK();
1872 		if (itp->qpt != 0) {
1873 			querier_present_timers_running = 1;
1874 		}
1875 		if (itp->it != 0) {
1876 			interface_timers_running = 1;
1877 		}
1878 		if (itp->cst != 0) {
1879 			current_state_timers_running = 1;
1880 		}
1881 		if (itp->sct != 0) {
1882 			state_change_timers_running = 1;
1883 		}
1884 		igmp_sched_timeout();
1885 		IGMP_UNLOCK();
1886 	}
1887 }
1888 
1889 /*
1890  * IGMP timer handler (per 1 second).
1891  */
1892 static void
igmp_timeout(void * arg)1893 igmp_timeout(void *arg)
1894 {
1895 #pragma unused(arg)
1896 	struct ifqueue           scq;   /* State-change packets */
1897 	struct ifqueue           qrq;   /* Query response packets */
1898 	struct ifnet            *ifp;
1899 	struct igmp_ifinfo      *igi;
1900 	struct in_multi         *inm;
1901 	unsigned int             loop = 0, uri_sec = 0;
1902 	SLIST_HEAD(, in_multi)  inm_dthead;
1903 
1904 	SLIST_INIT(&inm_dthead);
1905 
1906 	/*
1907 	 * Update coarse-grained networking timestamp (in sec.); the idea
1908 	 * is to piggy-back on the timeout callout to update the counter
1909 	 * returnable via net_uptime().
1910 	 */
1911 	net_update_uptime();
1912 
1913 	IGMP_LOCK();
1914 
1915 	IGMP_PRINTF(("%s: qpt %d, it %d, cst %d, sct %d\n", __func__,
1916 	    querier_present_timers_running, interface_timers_running,
1917 	    current_state_timers_running, state_change_timers_running));
1918 
1919 	/*
1920 	 * IGMPv1/v2 querier present timer processing.
1921 	 */
1922 	if (querier_present_timers_running) {
1923 		querier_present_timers_running = 0;
1924 		LIST_FOREACH(igi, &igi_head, igi_link) {
1925 			IGI_LOCK(igi);
1926 			igmp_v1v2_process_querier_timers(igi);
1927 			if (igi->igi_v1_timer > 0 || igi->igi_v2_timer > 0) {
1928 				querier_present_timers_running = 1;
1929 			}
1930 			IGI_UNLOCK(igi);
1931 		}
1932 	}
1933 
1934 	/*
1935 	 * IGMPv3 General Query response timer processing.
1936 	 */
1937 	if (interface_timers_running) {
1938 		IGMP_PRINTF(("%s: interface timers running\n", __func__));
1939 		interface_timers_running = 0;
1940 		LIST_FOREACH(igi, &igi_head, igi_link) {
1941 			IGI_LOCK(igi);
1942 			if (igi->igi_version != IGMP_VERSION_3) {
1943 				IGI_UNLOCK(igi);
1944 				continue;
1945 			}
1946 			if (igi->igi_v3_timer == 0) {
1947 				/* Do nothing. */
1948 			} else if (--igi->igi_v3_timer == 0) {
1949 				if (igmp_v3_dispatch_general_query(igi) > 0) {
1950 					interface_timers_running = 1;
1951 				}
1952 			} else {
1953 				interface_timers_running = 1;
1954 			}
1955 			IGI_UNLOCK(igi);
1956 		}
1957 	}
1958 
1959 	if (!current_state_timers_running &&
1960 	    !state_change_timers_running) {
1961 		goto out_locked;
1962 	}
1963 
1964 	current_state_timers_running = 0;
1965 	state_change_timers_running = 0;
1966 
1967 	memset(&qrq, 0, sizeof(struct ifqueue));
1968 	qrq.ifq_maxlen = IGMP_MAX_G_GS_PACKETS;
1969 
1970 	memset(&scq, 0, sizeof(struct ifqueue));
1971 	scq.ifq_maxlen =  IGMP_MAX_STATE_CHANGE_PACKETS;
1972 
1973 	IGMP_PRINTF(("%s: state change timers running\n", __func__));
1974 
1975 	/*
1976 	 * IGMPv1/v2/v3 host report and state-change timer processing.
1977 	 * Note: Processing a v3 group timer may remove a node.
1978 	 */
1979 	LIST_FOREACH(igi, &igi_head, igi_link) {
1980 		struct in_multistep step;
1981 
1982 		IGI_LOCK(igi);
1983 		ifp = igi->igi_ifp;
1984 		loop = (igi->igi_flags & IGIF_LOOPBACK) ? 1 : 0;
1985 		uri_sec = IGMP_RANDOM_DELAY(igi->igi_uri);
1986 		IGI_UNLOCK(igi);
1987 
1988 		in_multihead_lock_shared();
1989 		IN_FIRST_MULTI(step, inm);
1990 		while (inm != NULL) {
1991 			INM_LOCK(inm);
1992 			if (inm->inm_ifp != ifp) {
1993 				goto next;
1994 			}
1995 
1996 			IGI_LOCK(igi);
1997 			switch (igi->igi_version) {
1998 			case IGMP_VERSION_1:
1999 			case IGMP_VERSION_2:
2000 				igmp_v1v2_process_group_timer(inm,
2001 				    igi->igi_version);
2002 				break;
2003 			case IGMP_VERSION_3:
2004 				igmp_v3_process_group_timers(igi, &qrq,
2005 				    &scq, inm, uri_sec);
2006 				break;
2007 			}
2008 			IGI_UNLOCK(igi);
2009 next:
2010 			INM_UNLOCK(inm);
2011 			IN_NEXT_MULTI(step, inm);
2012 		}
2013 		in_multihead_lock_done();
2014 
2015 		IGI_LOCK(igi);
2016 		if (igi->igi_version == IGMP_VERSION_1 ||
2017 		    igi->igi_version == IGMP_VERSION_2) {
2018 			igmp_dispatch_queue(igi, &igi->igi_v2q, 0, loop);
2019 		} else if (igi->igi_version == IGMP_VERSION_3) {
2020 			IGI_UNLOCK(igi);
2021 			igmp_dispatch_queue(NULL, &qrq, 0, loop);
2022 			igmp_dispatch_queue(NULL, &scq, 0, loop);
2023 			VERIFY(qrq.ifq_len == 0);
2024 			VERIFY(scq.ifq_len == 0);
2025 			IGI_LOCK(igi);
2026 		}
2027 		/*
2028 		 * In case there are still any pending membership reports
2029 		 * which didn't get drained at version change time.
2030 		 */
2031 		IF_DRAIN(&igi->igi_v2q);
2032 		/*
2033 		 * Release all deferred inm records, and drain any locally
2034 		 * enqueued packets; do it even if the current IGMP version
2035 		 * for the link is no longer IGMPv3, in order to handle the
2036 		 * version change case.
2037 		 */
2038 		igmp_flush_relq(igi, (struct igmp_inm_relhead *)&inm_dthead);
2039 		VERIFY(SLIST_EMPTY(&igi->igi_relinmhead));
2040 		IGI_UNLOCK(igi);
2041 
2042 		IF_DRAIN(&qrq);
2043 		IF_DRAIN(&scq);
2044 	}
2045 
2046 out_locked:
2047 	/* re-arm the timer if there's work to do */
2048 	igmp_timeout_run = 0;
2049 	igmp_sched_timeout();
2050 	IGMP_UNLOCK();
2051 
2052 	/* Now that we're dropped all locks, release detached records */
2053 	IGMP_REMOVE_DETACHED_INM(&inm_dthead);
2054 }
2055 
2056 static void
igmp_sched_timeout(void)2057 igmp_sched_timeout(void)
2058 {
2059 	IGMP_LOCK_ASSERT_HELD();
2060 
2061 	if (!igmp_timeout_run &&
2062 	    (querier_present_timers_running || current_state_timers_running ||
2063 	    interface_timers_running || state_change_timers_running)) {
2064 		igmp_timeout_run = 1;
2065 		timeout(igmp_timeout, NULL, hz);
2066 	}
2067 }
2068 
2069 /*
2070  * Free the in_multi reference(s) for this IGMP lifecycle.
2071  *
2072  * Caller must be holding igi_lock.
2073  */
2074 static void
igmp_flush_relq(struct igmp_ifinfo * igi,struct igmp_inm_relhead * inm_dthead)2075 igmp_flush_relq(struct igmp_ifinfo *igi, struct igmp_inm_relhead *inm_dthead)
2076 {
2077 	struct in_multi *inm;
2078 
2079 again:
2080 	IGI_LOCK_ASSERT_HELD(igi);
2081 	inm = SLIST_FIRST(&igi->igi_relinmhead);
2082 	if (inm != NULL) {
2083 		int lastref;
2084 
2085 		SLIST_REMOVE_HEAD(&igi->igi_relinmhead, inm_nrele);
2086 		IGI_UNLOCK(igi);
2087 
2088 		in_multihead_lock_exclusive();
2089 		INM_LOCK(inm);
2090 		VERIFY(inm->inm_nrelecnt != 0);
2091 		inm->inm_nrelecnt--;
2092 		lastref = in_multi_detach(inm);
2093 		VERIFY(!lastref || (!(inm->inm_debug & IFD_ATTACHED) &&
2094 		    inm->inm_reqcnt == 0));
2095 		INM_UNLOCK(inm);
2096 		in_multihead_lock_done();
2097 		/* from igi_relinmhead */
2098 		INM_REMREF(inm);
2099 		/* from in_multihead list */
2100 		if (lastref) {
2101 			/*
2102 			 * Defer releasing our final reference, as we
2103 			 * are holding the IGMP lock at this point, and
2104 			 * we could end up with locking issues later on
2105 			 * (while issuing SIOCDELMULTI) when this is the
2106 			 * final reference count.  Let the caller do it
2107 			 * when it is safe.
2108 			 */
2109 			IGMP_ADD_DETACHED_INM(inm_dthead, inm);
2110 		}
2111 		IGI_LOCK(igi);
2112 		goto again;
2113 	}
2114 }
2115 
2116 /*
2117  * Update host report group timer for IGMPv1/v2.
2118  * Will update the global pending timer flags.
2119  */
2120 static void
igmp_v1v2_process_group_timer(struct in_multi * inm,const int igmp_version)2121 igmp_v1v2_process_group_timer(struct in_multi *inm, const int igmp_version)
2122 {
2123 	int report_timer_expired;
2124 
2125 	IGMP_LOCK_ASSERT_HELD();
2126 	INM_LOCK_ASSERT_HELD(inm);
2127 	IGI_LOCK_ASSERT_HELD(inm->inm_igi);
2128 
2129 	if (inm->inm_timer == 0) {
2130 		report_timer_expired = 0;
2131 	} else if (--inm->inm_timer == 0) {
2132 		report_timer_expired = 1;
2133 	} else {
2134 		current_state_timers_running = 1;
2135 		/* caller will schedule timer */
2136 		return;
2137 	}
2138 
2139 	switch (inm->inm_state) {
2140 	case IGMP_NOT_MEMBER:
2141 	case IGMP_SILENT_MEMBER:
2142 	case IGMP_IDLE_MEMBER:
2143 	case IGMP_LAZY_MEMBER:
2144 	case IGMP_SLEEPING_MEMBER:
2145 	case IGMP_AWAKENING_MEMBER:
2146 		break;
2147 	case IGMP_REPORTING_MEMBER:
2148 		if (report_timer_expired) {
2149 			inm->inm_state = IGMP_IDLE_MEMBER;
2150 			(void) igmp_v1v2_queue_report(inm,
2151 			    (igmp_version == IGMP_VERSION_2) ?
2152 			    IGMP_v2_HOST_MEMBERSHIP_REPORT :
2153 			    IGMP_v1_HOST_MEMBERSHIP_REPORT);
2154 			INM_LOCK_ASSERT_HELD(inm);
2155 			IGI_LOCK_ASSERT_HELD(inm->inm_igi);
2156 		}
2157 		break;
2158 	case IGMP_G_QUERY_PENDING_MEMBER:
2159 	case IGMP_SG_QUERY_PENDING_MEMBER:
2160 	case IGMP_LEAVING_MEMBER:
2161 		break;
2162 	}
2163 }
2164 
2165 /*
2166  * Update a group's timers for IGMPv3.
2167  * Will update the global pending timer flags.
2168  * Note: Unlocked read from igi.
2169  */
2170 static void
igmp_v3_process_group_timers(struct igmp_ifinfo * igi,struct ifqueue * qrq,struct ifqueue * scq,struct in_multi * inm,const unsigned int uri_sec)2171 igmp_v3_process_group_timers(struct igmp_ifinfo *igi,
2172     struct ifqueue *qrq, struct ifqueue *scq,
2173     struct in_multi *inm, const unsigned int uri_sec)
2174 {
2175 	int query_response_timer_expired;
2176 	int state_change_retransmit_timer_expired;
2177 
2178 	IGMP_LOCK_ASSERT_HELD();
2179 	INM_LOCK_ASSERT_HELD(inm);
2180 	IGI_LOCK_ASSERT_HELD(igi);
2181 	VERIFY(igi == inm->inm_igi);
2182 
2183 	query_response_timer_expired = 0;
2184 	state_change_retransmit_timer_expired = 0;
2185 
2186 	/*
2187 	 * During a transition from v1/v2 compatibility mode back to v3,
2188 	 * a group record in REPORTING state may still have its group
2189 	 * timer active. This is a no-op in this function; it is easier
2190 	 * to deal with it here than to complicate the timeout path.
2191 	 */
2192 	if (inm->inm_timer == 0) {
2193 		query_response_timer_expired = 0;
2194 	} else if (--inm->inm_timer == 0) {
2195 		query_response_timer_expired = 1;
2196 	} else {
2197 		current_state_timers_running = 1;
2198 		/* caller will schedule timer */
2199 	}
2200 
2201 	if (inm->inm_sctimer == 0) {
2202 		state_change_retransmit_timer_expired = 0;
2203 	} else if (--inm->inm_sctimer == 0) {
2204 		state_change_retransmit_timer_expired = 1;
2205 	} else {
2206 		state_change_timers_running = 1;
2207 		/* caller will schedule timer */
2208 	}
2209 
2210 	/* We are in timer callback, so be quick about it. */
2211 	if (!state_change_retransmit_timer_expired &&
2212 	    !query_response_timer_expired) {
2213 		return;
2214 	}
2215 
2216 	switch (inm->inm_state) {
2217 	case IGMP_NOT_MEMBER:
2218 	case IGMP_SILENT_MEMBER:
2219 	case IGMP_SLEEPING_MEMBER:
2220 	case IGMP_LAZY_MEMBER:
2221 	case IGMP_AWAKENING_MEMBER:
2222 	case IGMP_IDLE_MEMBER:
2223 		break;
2224 	case IGMP_G_QUERY_PENDING_MEMBER:
2225 	case IGMP_SG_QUERY_PENDING_MEMBER:
2226 		/*
2227 		 * Respond to a previously pending Group-Specific
2228 		 * or Group-and-Source-Specific query by enqueueing
2229 		 * the appropriate Current-State report for
2230 		 * immediate transmission.
2231 		 */
2232 		if (query_response_timer_expired) {
2233 			int retval;
2234 
2235 			retval = igmp_v3_enqueue_group_record(qrq, inm, 0, 1,
2236 			    (inm->inm_state == IGMP_SG_QUERY_PENDING_MEMBER));
2237 			IGMP_PRINTF(("%s: enqueue record = %d\n",
2238 			    __func__, retval));
2239 			inm->inm_state = IGMP_REPORTING_MEMBER;
2240 			/* XXX Clear recorded sources for next time. */
2241 			inm_clear_recorded(inm);
2242 		}
2243 		OS_FALLTHROUGH;
2244 	case IGMP_REPORTING_MEMBER:
2245 	case IGMP_LEAVING_MEMBER:
2246 		if (state_change_retransmit_timer_expired) {
2247 			/*
2248 			 * State-change retransmission timer fired.
2249 			 * If there are any further pending retransmissions,
2250 			 * set the global pending state-change flag, and
2251 			 * reset the timer.
2252 			 */
2253 			if (--inm->inm_scrv > 0) {
2254 				inm->inm_sctimer = (uint16_t)uri_sec;
2255 				state_change_timers_running = 1;
2256 				/* caller will schedule timer */
2257 			}
2258 			/*
2259 			 * Retransmit the previously computed state-change
2260 			 * report. If there are no further pending
2261 			 * retransmissions, the mbuf queue will be consumed.
2262 			 * Update T0 state to T1 as we have now sent
2263 			 * a state-change.
2264 			 */
2265 			(void) igmp_v3_merge_state_changes(inm, scq);
2266 
2267 			inm_commit(inm);
2268 			IGMP_INET_PRINTF(inm->inm_addr,
2269 			    ("%s: T1 -> T0 for %s/%s\n", __func__,
2270 			    _igmp_inet_buf, if_name(inm->inm_ifp)));
2271 
2272 			/*
2273 			 * If we are leaving the group for good, make sure
2274 			 * we release IGMP's reference to it.
2275 			 * This release must be deferred using a SLIST,
2276 			 * as we are called from a loop which traverses
2277 			 * the in_multihead list.
2278 			 */
2279 			if (inm->inm_state == IGMP_LEAVING_MEMBER &&
2280 			    inm->inm_scrv == 0) {
2281 				inm->inm_state = IGMP_NOT_MEMBER;
2282 				/*
2283 				 * A reference has already been held in
2284 				 * igmp_final_leave() for this inm, so
2285 				 * no need to hold another one.  We also
2286 				 * bumped up its request count then, so
2287 				 * that it stays in in_multihead.  Both
2288 				 * of them will be released when it is
2289 				 * dequeued later on.
2290 				 */
2291 				VERIFY(inm->inm_nrelecnt != 0);
2292 				SLIST_INSERT_HEAD(&igi->igi_relinmhead,
2293 				    inm, inm_nrele);
2294 			}
2295 		}
2296 		break;
2297 	}
2298 }
2299 
2300 /*
2301  * Suppress a group's pending response to a group or source/group query.
2302  *
2303  * Do NOT suppress state changes. This leads to IGMPv3 inconsistency.
2304  * Do NOT update ST1/ST0 as this operation merely suppresses
2305  * the currently pending group record.
2306  * Do NOT suppress the response to a general query. It is possible but
2307  * it would require adding another state or flag.
2308  */
2309 static void
igmp_v3_suppress_group_record(struct in_multi * inm)2310 igmp_v3_suppress_group_record(struct in_multi *inm)
2311 {
2312 	INM_LOCK_ASSERT_HELD(inm);
2313 	IGI_LOCK_ASSERT_HELD(inm->inm_igi);
2314 
2315 	VERIFY(inm->inm_igi->igi_version == IGMP_VERSION_3);
2316 
2317 	if (inm->inm_state != IGMP_G_QUERY_PENDING_MEMBER ||
2318 	    inm->inm_state != IGMP_SG_QUERY_PENDING_MEMBER) {
2319 		return;
2320 	}
2321 
2322 	if (inm->inm_state == IGMP_SG_QUERY_PENDING_MEMBER) {
2323 		inm_clear_recorded(inm);
2324 	}
2325 
2326 	inm->inm_timer = 0;
2327 	inm->inm_state = IGMP_REPORTING_MEMBER;
2328 }
2329 
2330 /*
2331  * Switch to a different IGMP version on the given interface,
2332  * as per Section 7.2.1.
2333  */
2334 static uint32_t
igmp_set_version(struct igmp_ifinfo * igi,const int igmp_version)2335 igmp_set_version(struct igmp_ifinfo *igi, const int igmp_version)
2336 {
2337 	int old_version_timer;
2338 
2339 	IGI_LOCK_ASSERT_HELD(igi);
2340 
2341 	IGMP_PRINTF(("%s: switching to v%d on ifp 0x%llx(%s)\n", __func__,
2342 	    igmp_version, (uint64_t)VM_KERNEL_ADDRPERM(igi->igi_ifp),
2343 	    if_name(igi->igi_ifp)));
2344 
2345 	if (igmp_version == IGMP_VERSION_1 || igmp_version == IGMP_VERSION_2) {
2346 		/*
2347 		 * Compute the "Older Version Querier Present" timer as per
2348 		 * Section 8.12, in seconds.
2349 		 */
2350 		old_version_timer = igi->igi_rv * igi->igi_qi + igi->igi_qri;
2351 
2352 		if (igmp_version == IGMP_VERSION_1) {
2353 			igi->igi_v1_timer = old_version_timer;
2354 			igi->igi_v2_timer = 0;
2355 		} else if (igmp_version == IGMP_VERSION_2) {
2356 			igi->igi_v1_timer = 0;
2357 			igi->igi_v2_timer = old_version_timer;
2358 		}
2359 	}
2360 
2361 	if (igi->igi_v1_timer == 0 && igi->igi_v2_timer > 0) {
2362 		if (igi->igi_version != IGMP_VERSION_2) {
2363 			igi->igi_version = IGMP_VERSION_2;
2364 			igmp_v3_cancel_link_timers(igi);
2365 		}
2366 	} else if (igi->igi_v1_timer > 0) {
2367 		if (igi->igi_version != IGMP_VERSION_1) {
2368 			igi->igi_version = IGMP_VERSION_1;
2369 			igmp_v3_cancel_link_timers(igi);
2370 		}
2371 	}
2372 
2373 	IGI_LOCK_ASSERT_HELD(igi);
2374 
2375 	return MAX(igi->igi_v1_timer, igi->igi_v2_timer);
2376 }
2377 
2378 /*
2379  * Cancel pending IGMPv3 timers for the given link and all groups
2380  * joined on it; state-change, general-query, and group-query timers.
2381  *
2382  * Only ever called on a transition from v3 to Compatibility mode. Kill
2383  * the timers stone dead (this may be expensive for large N groups), they
2384  * will be restarted if Compatibility Mode deems that they must be due to
2385  * query processing.
2386  */
2387 static void
igmp_v3_cancel_link_timers(struct igmp_ifinfo * igi)2388 igmp_v3_cancel_link_timers(struct igmp_ifinfo *igi)
2389 {
2390 	struct ifnet            *ifp;
2391 	struct in_multi         *inm;
2392 	struct in_multistep     step;
2393 
2394 	IGI_LOCK_ASSERT_HELD(igi);
2395 
2396 	IGMP_PRINTF(("%s: cancel v3 timers on ifp 0x%llx(%s)\n", __func__,
2397 	    (uint64_t)VM_KERNEL_ADDRPERM(igi->igi_ifp), if_name(igi->igi_ifp)));
2398 
2399 	/*
2400 	 * Stop the v3 General Query Response on this link stone dead.
2401 	 * If timer is woken up due to interface_timers_running,
2402 	 * the flag will be cleared if there are no pending link timers.
2403 	 */
2404 	igi->igi_v3_timer = 0;
2405 
2406 	/*
2407 	 * Now clear the current-state and state-change report timers
2408 	 * for all memberships scoped to this link.
2409 	 */
2410 	ifp = igi->igi_ifp;
2411 	IGI_UNLOCK(igi);
2412 
2413 	in_multihead_lock_shared();
2414 	IN_FIRST_MULTI(step, inm);
2415 	while (inm != NULL) {
2416 		INM_LOCK(inm);
2417 		if (inm->inm_ifp != ifp) {
2418 			goto next;
2419 		}
2420 
2421 		switch (inm->inm_state) {
2422 		case IGMP_NOT_MEMBER:
2423 		case IGMP_SILENT_MEMBER:
2424 		case IGMP_IDLE_MEMBER:
2425 		case IGMP_LAZY_MEMBER:
2426 		case IGMP_SLEEPING_MEMBER:
2427 		case IGMP_AWAKENING_MEMBER:
2428 			/*
2429 			 * These states are either not relevant in v3 mode,
2430 			 * or are unreported. Do nothing.
2431 			 */
2432 			break;
2433 		case IGMP_LEAVING_MEMBER:
2434 			/*
2435 			 * If we are leaving the group and switching to
2436 			 * compatibility mode, we need to release the final
2437 			 * reference held for issuing the INCLUDE {}, and
2438 			 * transition to REPORTING to ensure the host leave
2439 			 * message is sent upstream to the old querier --
2440 			 * transition to NOT would lose the leave and race.
2441 			 * During igmp_final_leave(), we bumped up both the
2442 			 * request and reference counts.  Since we cannot
2443 			 * call in_multi_detach() here, defer this task to
2444 			 * the timer routine.
2445 			 */
2446 			VERIFY(inm->inm_nrelecnt != 0);
2447 			IGI_LOCK(igi);
2448 			SLIST_INSERT_HEAD(&igi->igi_relinmhead, inm, inm_nrele);
2449 			IGI_UNLOCK(igi);
2450 			OS_FALLTHROUGH;
2451 		case IGMP_G_QUERY_PENDING_MEMBER:
2452 		case IGMP_SG_QUERY_PENDING_MEMBER:
2453 			inm_clear_recorded(inm);
2454 			OS_FALLTHROUGH;
2455 		case IGMP_REPORTING_MEMBER:
2456 			inm->inm_state = IGMP_REPORTING_MEMBER;
2457 			break;
2458 		}
2459 		/*
2460 		 * Always clear state-change and group report timers.
2461 		 * Free any pending IGMPv3 state-change records.
2462 		 */
2463 		inm->inm_sctimer = 0;
2464 		inm->inm_timer = 0;
2465 		IF_DRAIN(&inm->inm_scq);
2466 next:
2467 		INM_UNLOCK(inm);
2468 		IN_NEXT_MULTI(step, inm);
2469 	}
2470 	in_multihead_lock_done();
2471 
2472 	IGI_LOCK(igi);
2473 }
2474 
2475 /*
2476  * Update the Older Version Querier Present timers for a link.
2477  * See Section 7.2.1 of RFC 3376.
2478  */
2479 static void
igmp_v1v2_process_querier_timers(struct igmp_ifinfo * igi)2480 igmp_v1v2_process_querier_timers(struct igmp_ifinfo *igi)
2481 {
2482 	IGI_LOCK_ASSERT_HELD(igi);
2483 
2484 	if (igi->igi_v1_timer == 0 && igi->igi_v2_timer == 0) {
2485 		/*
2486 		 * IGMPv1 and IGMPv2 Querier Present timers expired.
2487 		 *
2488 		 * Revert to IGMPv3.
2489 		 */
2490 		if (igi->igi_version != IGMP_VERSION_3) {
2491 			IGMP_PRINTF(("%s: transition from v%d -> v%d "
2492 			    "on 0x%llx(%s)\n", __func__,
2493 			    igi->igi_version, IGMP_VERSION_3,
2494 			    (uint64_t)VM_KERNEL_ADDRPERM(igi->igi_ifp),
2495 			    if_name(igi->igi_ifp)));
2496 			igi->igi_version = IGMP_VERSION_3;
2497 			IF_DRAIN(&igi->igi_v2q);
2498 		}
2499 	} else if (igi->igi_v1_timer == 0 && igi->igi_v2_timer > 0) {
2500 		/*
2501 		 * IGMPv1 Querier Present timer expired,
2502 		 * IGMPv2 Querier Present timer running.
2503 		 * If IGMPv2 was disabled since last timeout,
2504 		 * revert to IGMPv3.
2505 		 * If IGMPv2 is enabled, revert to IGMPv2.
2506 		 */
2507 		if (!igmp_v2enable) {
2508 			IGMP_PRINTF(("%s: transition from v%d -> v%d "
2509 			    "on 0x%llx(%s%d)\n", __func__,
2510 			    igi->igi_version, IGMP_VERSION_3,
2511 			    (uint64_t)VM_KERNEL_ADDRPERM(igi->igi_ifp),
2512 			    igi->igi_ifp->if_name, igi->igi_ifp->if_unit));
2513 			igi->igi_v2_timer = 0;
2514 			igi->igi_version = IGMP_VERSION_3;
2515 			IF_DRAIN(&igi->igi_v2q);
2516 		} else {
2517 			--igi->igi_v2_timer;
2518 			if (igi->igi_version != IGMP_VERSION_2) {
2519 				IGMP_PRINTF(("%s: transition from v%d -> v%d "
2520 				    "on 0x%llx(%s)\n", __func__,
2521 				    igi->igi_version, IGMP_VERSION_2,
2522 				    (uint64_t)VM_KERNEL_ADDRPERM(igi->igi_ifp),
2523 				    if_name(igi->igi_ifp)));
2524 				igi->igi_version = IGMP_VERSION_2;
2525 				IF_DRAIN(&igi->igi_gq);
2526 				igmp_v3_cancel_link_timers(igi);
2527 			}
2528 		}
2529 	} else if (igi->igi_v1_timer > 0) {
2530 		/*
2531 		 * IGMPv1 Querier Present timer running.
2532 		 * Stop IGMPv2 timer if running.
2533 		 *
2534 		 * If IGMPv1 was disabled since last timeout,
2535 		 * revert to IGMPv3.
2536 		 * If IGMPv1 is enabled, reset IGMPv2 timer if running.
2537 		 */
2538 		if (!igmp_v1enable) {
2539 			IGMP_PRINTF(("%s: transition from v%d -> v%d "
2540 			    "on 0x%llx(%s%d)\n", __func__,
2541 			    igi->igi_version, IGMP_VERSION_3,
2542 			    (uint64_t)VM_KERNEL_ADDRPERM(igi->igi_ifp),
2543 			    igi->igi_ifp->if_name, igi->igi_ifp->if_unit));
2544 			igi->igi_v1_timer = 0;
2545 			igi->igi_version = IGMP_VERSION_3;
2546 			IF_DRAIN(&igi->igi_v2q);
2547 		} else {
2548 			--igi->igi_v1_timer;
2549 		}
2550 		if (igi->igi_v2_timer > 0) {
2551 			IGMP_PRINTF(("%s: cancel v2 timer on 0x%llx(%s%d)\n",
2552 			    __func__,
2553 			    (uint64_t)VM_KERNEL_ADDRPERM(igi->igi_ifp),
2554 			    igi->igi_ifp->if_name, igi->igi_ifp->if_unit));
2555 			igi->igi_v2_timer = 0;
2556 		}
2557 	}
2558 }
2559 
2560 /*
2561  * Dispatch an IGMPv1/v2 host report or leave message.
2562  * These are always small enough to fit inside a single mbuf.
2563  */
2564 static int
igmp_v1v2_queue_report(struct in_multi * inm,const int type)2565 igmp_v1v2_queue_report(struct in_multi *inm, const int type)
2566 {
2567 	struct ifnet            *ifp;
2568 	struct igmp             *igmp;
2569 	struct ip               *ip;
2570 	struct mbuf             *m;
2571 	int                     error = 0;
2572 
2573 	INM_LOCK_ASSERT_HELD(inm);
2574 	IGI_LOCK_ASSERT_HELD(inm->inm_igi);
2575 
2576 	ifp = inm->inm_ifp;
2577 
2578 	MGETHDR(m, M_DONTWAIT, MT_DATA);
2579 	if (m == NULL) {
2580 		return ENOMEM;
2581 	}
2582 	MH_ALIGN(m, sizeof(struct ip) + sizeof(struct igmp));
2583 
2584 	m->m_pkthdr.len = sizeof(struct ip) + sizeof(struct igmp);
2585 
2586 	m->m_data += sizeof(struct ip);
2587 	m->m_len = sizeof(struct igmp);
2588 
2589 	igmp = mtod(m, struct igmp *);
2590 	igmp->igmp_type = (u_char)type;
2591 	igmp->igmp_code = 0;
2592 	igmp->igmp_group = inm->inm_addr;
2593 	igmp->igmp_cksum = 0;
2594 	igmp->igmp_cksum = in_cksum(m, sizeof(struct igmp));
2595 
2596 	m->m_data -= sizeof(struct ip);
2597 	m->m_len += sizeof(struct ip);
2598 
2599 	ip = mtod(m, struct ip *);
2600 	ip->ip_tos = 0;
2601 	ip->ip_len = sizeof(struct ip) + sizeof(struct igmp);
2602 	ip->ip_off = 0;
2603 	ip->ip_p = IPPROTO_IGMP;
2604 	ip->ip_src.s_addr = INADDR_ANY;
2605 
2606 	if (type == IGMP_HOST_LEAVE_MESSAGE) {
2607 		ip->ip_dst.s_addr = htonl(INADDR_ALLRTRS_GROUP);
2608 	} else {
2609 		ip->ip_dst = inm->inm_addr;
2610 	}
2611 
2612 	igmp_save_context(m, ifp);
2613 
2614 	m->m_flags |= M_IGMPV2;
2615 	if (inm->inm_igi->igi_flags & IGIF_LOOPBACK) {
2616 		m->m_flags |= M_IGMP_LOOP;
2617 	}
2618 
2619 	/*
2620 	 * Due to the fact that at this point we are possibly holding
2621 	 * in_multihead_lock in shared or exclusive mode, we can't call
2622 	 * igmp_sendpkt() here since that will eventually call ip_output(),
2623 	 * which will try to lock in_multihead_lock and cause a deadlock.
2624 	 * Instead we defer the work to the igmp_timeout() thread, thus
2625 	 * avoiding unlocking in_multihead_lock here.
2626 	 */
2627 	if (IF_QFULL(&inm->inm_igi->igi_v2q)) {
2628 		IGMP_PRINTF(("%s: v1/v2 outbound queue full\n", __func__));
2629 		error = ENOMEM;
2630 		m_freem(m);
2631 	} else {
2632 		IF_ENQUEUE(&inm->inm_igi->igi_v2q, m);
2633 		VERIFY(error == 0);
2634 	}
2635 	return error;
2636 }
2637 
2638 /*
2639  * Process a state change from the upper layer for the given IPv4 group.
2640  *
2641  * Each socket holds a reference on the in_multi in its own ip_moptions.
2642  * The socket layer will have made the necessary updates to the group
2643  * state, it is now up to IGMP to issue a state change report if there
2644  * has been any change between T0 (when the last state-change was issued)
2645  * and T1 (now).
2646  *
2647  * We use the IGMPv3 state machine at group level. The IGMP module
2648  * however makes the decision as to which IGMP protocol version to speak.
2649  * A state change *from* INCLUDE {} always means an initial join.
2650  * A state change *to* INCLUDE {} always means a final leave.
2651  *
2652  * FUTURE: If IGIF_V3LITE is enabled for this interface, then we can
2653  * save ourselves a bunch of work; any exclusive mode groups need not
2654  * compute source filter lists.
2655  */
2656 int
igmp_change_state(struct in_multi * inm,struct igmp_tparams * itp)2657 igmp_change_state(struct in_multi *inm, struct igmp_tparams *itp)
2658 {
2659 	struct igmp_ifinfo *igi;
2660 	struct ifnet *ifp;
2661 	int error = 0;
2662 
2663 	VERIFY(itp != NULL);
2664 	bzero(itp, sizeof(*itp));
2665 
2666 	INM_LOCK_ASSERT_HELD(inm);
2667 	VERIFY(inm->inm_igi != NULL);
2668 	IGI_LOCK_ASSERT_NOTHELD(inm->inm_igi);
2669 
2670 	/*
2671 	 * Try to detect if the upper layer just asked us to change state
2672 	 * for an interface which has now gone away.
2673 	 */
2674 	VERIFY(inm->inm_ifma != NULL);
2675 	ifp = inm->inm_ifma->ifma_ifp;
2676 	/*
2677 	 * Sanity check that netinet's notion of ifp is the same as net's.
2678 	 */
2679 	VERIFY(inm->inm_ifp == ifp);
2680 
2681 	igi = IGMP_IFINFO(ifp);
2682 	VERIFY(igi != NULL);
2683 
2684 	/*
2685 	 * If we detect a state transition to or from MCAST_UNDEFINED
2686 	 * for this group, then we are starting or finishing an IGMP
2687 	 * life cycle for this group.
2688 	 */
2689 	if (inm->inm_st[1].iss_fmode != inm->inm_st[0].iss_fmode) {
2690 		IGMP_PRINTF(("%s: inm transition %d -> %d\n", __func__,
2691 		    inm->inm_st[0].iss_fmode, inm->inm_st[1].iss_fmode));
2692 		if (inm->inm_st[0].iss_fmode == MCAST_UNDEFINED) {
2693 			IGMP_PRINTF(("%s: initial join\n", __func__));
2694 			error = igmp_initial_join(inm, igi, itp);
2695 			goto out;
2696 		} else if (inm->inm_st[1].iss_fmode == MCAST_UNDEFINED) {
2697 			IGMP_PRINTF(("%s: final leave\n", __func__));
2698 			igmp_final_leave(inm, igi, itp);
2699 			goto out;
2700 		}
2701 	} else {
2702 		IGMP_PRINTF(("%s: filter set change\n", __func__));
2703 	}
2704 
2705 	error = igmp_handle_state_change(inm, igi, itp);
2706 out:
2707 	return error;
2708 }
2709 
2710 /*
2711  * Perform the initial join for an IGMP group.
2712  *
2713  * When joining a group:
2714  *  If the group should have its IGMP traffic suppressed, do nothing.
2715  *  IGMPv1 starts sending IGMPv1 host membership reports.
2716  *  IGMPv2 starts sending IGMPv2 host membership reports.
2717  *  IGMPv3 will schedule an IGMPv3 state-change report containing the
2718  *  initial state of the membership.
2719  */
2720 static int
igmp_initial_join(struct in_multi * inm,struct igmp_ifinfo * igi,struct igmp_tparams * itp)2721 igmp_initial_join(struct in_multi *inm, struct igmp_ifinfo *igi,
2722     struct igmp_tparams *itp)
2723 {
2724 	struct ifnet            *ifp;
2725 	struct ifqueue          *ifq;
2726 	int                      error, retval, syncstates;
2727 
2728 	INM_LOCK_ASSERT_HELD(inm);
2729 	IGI_LOCK_ASSERT_NOTHELD(igi);
2730 	VERIFY(itp != NULL);
2731 
2732 	IGMP_INET_PRINTF(inm->inm_addr,
2733 	    ("%s: initial join %s on ifp 0x%llx(%s)\n", __func__,
2734 	    _igmp_inet_buf, (uint64_t)VM_KERNEL_ADDRPERM(inm->inm_ifp),
2735 	    if_name(inm->inm_ifp)));
2736 
2737 	error = 0;
2738 	syncstates = 1;
2739 
2740 	ifp = inm->inm_ifp;
2741 
2742 	IGI_LOCK(igi);
2743 	VERIFY(igi->igi_ifp == ifp);
2744 
2745 	/*
2746 	 * Groups joined on loopback or marked as 'not reported',
2747 	 * e.g. 224.0.0.1, enter the IGMP_SILENT_MEMBER state and
2748 	 * are never reported in any IGMP protocol exchanges.
2749 	 * All other groups enter the appropriate IGMP state machine
2750 	 * for the version in use on this link.
2751 	 * A link marked as IGIF_SILENT causes IGMP to be completely
2752 	 * disabled for the link.
2753 	 */
2754 	if ((ifp->if_flags & IFF_LOOPBACK) ||
2755 	    (igi->igi_flags & IGIF_SILENT) ||
2756 	    !igmp_isgroupreported(inm->inm_addr)) {
2757 		IGMP_PRINTF(("%s: not kicking state machine for silent group\n",
2758 		    __func__));
2759 		inm->inm_state = IGMP_SILENT_MEMBER;
2760 		inm->inm_timer = 0;
2761 	} else {
2762 		/*
2763 		 * Deal with overlapping in_multi lifecycle.
2764 		 * If this group was LEAVING, then make sure
2765 		 * we drop the reference we picked up to keep the
2766 		 * group around for the final INCLUDE {} enqueue.
2767 		 * Since we cannot call in_multi_detach() here,
2768 		 * defer this task to the timer routine.
2769 		 */
2770 		if (igi->igi_version == IGMP_VERSION_3 &&
2771 		    inm->inm_state == IGMP_LEAVING_MEMBER) {
2772 			VERIFY(inm->inm_nrelecnt != 0);
2773 			SLIST_INSERT_HEAD(&igi->igi_relinmhead, inm, inm_nrele);
2774 		}
2775 
2776 		inm->inm_state = IGMP_REPORTING_MEMBER;
2777 
2778 		switch (igi->igi_version) {
2779 		case IGMP_VERSION_1:
2780 		case IGMP_VERSION_2:
2781 			inm->inm_state = IGMP_IDLE_MEMBER;
2782 			error = igmp_v1v2_queue_report(inm,
2783 			    (igi->igi_version == IGMP_VERSION_2) ?
2784 			    IGMP_v2_HOST_MEMBERSHIP_REPORT :
2785 			    IGMP_v1_HOST_MEMBERSHIP_REPORT);
2786 
2787 			INM_LOCK_ASSERT_HELD(inm);
2788 			IGI_LOCK_ASSERT_HELD(igi);
2789 
2790 			if (error == 0) {
2791 				inm->inm_timer =
2792 				    IGMP_RANDOM_DELAY(IGMP_V1V2_MAX_RI);
2793 				itp->cst = 1;
2794 			}
2795 			break;
2796 
2797 		case IGMP_VERSION_3:
2798 			/*
2799 			 * Defer update of T0 to T1, until the first copy
2800 			 * of the state change has been transmitted.
2801 			 */
2802 			syncstates = 0;
2803 
2804 			/*
2805 			 * Immediately enqueue a State-Change Report for
2806 			 * this interface, freeing any previous reports.
2807 			 * Don't kick the timers if there is nothing to do,
2808 			 * or if an error occurred.
2809 			 */
2810 			ifq = &inm->inm_scq;
2811 			IF_DRAIN(ifq);
2812 			retval = igmp_v3_enqueue_group_record(ifq, inm, 1,
2813 			    0, 0);
2814 			itp->cst = (ifq->ifq_len > 0);
2815 			IGMP_PRINTF(("%s: enqueue record = %d\n",
2816 			    __func__, retval));
2817 			if (retval <= 0) {
2818 				error = retval * -1;
2819 				break;
2820 			}
2821 
2822 			/*
2823 			 * Schedule transmission of pending state-change
2824 			 * report up to RV times for this link. The timer
2825 			 * will fire at the next igmp_timeout (1 second),
2826 			 * giving us an opportunity to merge the reports.
2827 			 */
2828 			if (igi->igi_flags & IGIF_LOOPBACK) {
2829 				inm->inm_scrv = 1;
2830 			} else {
2831 				VERIFY(igi->igi_rv > 1);
2832 				inm->inm_scrv = (uint16_t)igi->igi_rv;
2833 			}
2834 			inm->inm_sctimer = 1;
2835 			itp->sct = 1;
2836 
2837 			error = 0;
2838 			break;
2839 		}
2840 	}
2841 	IGI_UNLOCK(igi);
2842 
2843 	/*
2844 	 * Only update the T0 state if state change is atomic,
2845 	 * i.e. we don't need to wait for a timer to fire before we
2846 	 * can consider the state change to have been communicated.
2847 	 */
2848 	if (syncstates) {
2849 		inm_commit(inm);
2850 		IGMP_INET_PRINTF(inm->inm_addr,
2851 		    ("%s: T1 -> T0 for %s/%s\n", __func__,
2852 		    _igmp_inet_buf, if_name(inm->inm_ifp)));
2853 	}
2854 
2855 	return error;
2856 }
2857 
2858 /*
2859  * Issue an intermediate state change during the IGMP life-cycle.
2860  */
2861 static int
igmp_handle_state_change(struct in_multi * inm,struct igmp_ifinfo * igi,struct igmp_tparams * itp)2862 igmp_handle_state_change(struct in_multi *inm, struct igmp_ifinfo *igi,
2863     struct igmp_tparams *itp)
2864 {
2865 	struct ifnet            *ifp;
2866 	int                      retval = 0;
2867 
2868 	INM_LOCK_ASSERT_HELD(inm);
2869 	IGI_LOCK_ASSERT_NOTHELD(igi);
2870 	VERIFY(itp != NULL);
2871 
2872 	IGMP_INET_PRINTF(inm->inm_addr,
2873 	    ("%s: state change for %s on ifp 0x%llx(%s)\n", __func__,
2874 	    _igmp_inet_buf, (uint64_t)VM_KERNEL_ADDRPERM(inm->inm_ifp),
2875 	    if_name(inm->inm_ifp)));
2876 
2877 	ifp = inm->inm_ifp;
2878 
2879 	IGI_LOCK(igi);
2880 	VERIFY(igi->igi_ifp == ifp);
2881 
2882 	if ((ifp->if_flags & IFF_LOOPBACK) ||
2883 	    (igi->igi_flags & IGIF_SILENT) ||
2884 	    !igmp_isgroupreported(inm->inm_addr) ||
2885 	    (igi->igi_version != IGMP_VERSION_3)) {
2886 		IGI_UNLOCK(igi);
2887 		if (!igmp_isgroupreported(inm->inm_addr)) {
2888 			IGMP_PRINTF(("%s: not kicking state "
2889 			    "machine for silent group\n", __func__));
2890 		}
2891 		IGMP_PRINTF(("%s: nothing to do\n", __func__));
2892 		inm_commit(inm);
2893 		IGMP_INET_PRINTF(inm->inm_addr,
2894 		    ("%s: T1 -> T0 for %s/%s\n", __func__,
2895 		    _igmp_inet_buf, inm->inm_ifp->if_name));
2896 		goto done;
2897 	}
2898 
2899 	IF_DRAIN(&inm->inm_scq);
2900 
2901 	retval = igmp_v3_enqueue_group_record(&inm->inm_scq, inm, 1, 0, 0);
2902 	itp->cst = (inm->inm_scq.ifq_len > 0);
2903 	IGMP_PRINTF(("%s: enqueue record = %d\n", __func__, retval));
2904 	if (retval <= 0) {
2905 		IGI_UNLOCK(igi);
2906 		retval *= -1;
2907 		goto done;
2908 	}
2909 	/*
2910 	 * If record(s) were enqueued, start the state-change
2911 	 * report timer for this group.
2912 	 */
2913 	inm->inm_scrv = ((igi->igi_flags & IGIF_LOOPBACK) ? 1 : (uint16_t)igi->igi_rv);
2914 	inm->inm_sctimer = 1;
2915 	itp->sct = 1;
2916 	IGI_UNLOCK(igi);
2917 done:
2918 	return retval;
2919 }
2920 
2921 /*
2922  * Perform the final leave for an IGMP group.
2923  *
2924  * When leaving a group:
2925  *  IGMPv1 does nothing.
2926  *  IGMPv2 sends a host leave message, if and only if we are the reporter.
2927  *  IGMPv3 enqueues a state-change report containing a transition
2928  *  to INCLUDE {} for immediate transmission.
2929  */
2930 static void
igmp_final_leave(struct in_multi * inm,struct igmp_ifinfo * igi,struct igmp_tparams * itp)2931 igmp_final_leave(struct in_multi *inm, struct igmp_ifinfo *igi,
2932     struct igmp_tparams *itp)
2933 {
2934 	int syncstates = 1;
2935 
2936 	INM_LOCK_ASSERT_HELD(inm);
2937 	IGI_LOCK_ASSERT_NOTHELD(igi);
2938 	VERIFY(itp != NULL);
2939 
2940 	IGMP_INET_PRINTF(inm->inm_addr,
2941 	    ("%s: final leave %s on ifp 0x%llx(%s)\n", __func__,
2942 	    _igmp_inet_buf, (uint64_t)VM_KERNEL_ADDRPERM(inm->inm_ifp),
2943 	    if_name(inm->inm_ifp)));
2944 
2945 	switch (inm->inm_state) {
2946 	case IGMP_NOT_MEMBER:
2947 	case IGMP_SILENT_MEMBER:
2948 	case IGMP_LEAVING_MEMBER:
2949 		/* Already leaving or left; do nothing. */
2950 		IGMP_PRINTF(("%s: not kicking state machine for silent group\n",
2951 		    __func__));
2952 		break;
2953 	case IGMP_REPORTING_MEMBER:
2954 	case IGMP_IDLE_MEMBER:
2955 	case IGMP_G_QUERY_PENDING_MEMBER:
2956 	case IGMP_SG_QUERY_PENDING_MEMBER:
2957 		IGI_LOCK(igi);
2958 		if (igi->igi_version == IGMP_VERSION_2) {
2959 			if (inm->inm_state == IGMP_G_QUERY_PENDING_MEMBER ||
2960 			    inm->inm_state == IGMP_SG_QUERY_PENDING_MEMBER) {
2961 				panic("%s: IGMPv3 state reached, not IGMPv3 "
2962 				    "mode\n", __func__);
2963 				/* NOTREACHED */
2964 			}
2965 			/* scheduler timer if enqueue is successful */
2966 			itp->cst = (igmp_v1v2_queue_report(inm,
2967 			    IGMP_HOST_LEAVE_MESSAGE) == 0);
2968 
2969 			INM_LOCK_ASSERT_HELD(inm);
2970 			IGI_LOCK_ASSERT_HELD(igi);
2971 
2972 			inm->inm_state = IGMP_NOT_MEMBER;
2973 		} else if (igi->igi_version == IGMP_VERSION_3) {
2974 			/*
2975 			 * Stop group timer and all pending reports.
2976 			 * Immediately enqueue a state-change report
2977 			 * TO_IN {} to be sent on the next timeout,
2978 			 * giving us an opportunity to merge reports.
2979 			 */
2980 			IF_DRAIN(&inm->inm_scq);
2981 			inm->inm_timer = 0;
2982 			if (igi->igi_flags & IGIF_LOOPBACK) {
2983 				inm->inm_scrv = 1;
2984 			} else {
2985 				inm->inm_scrv = (uint16_t)igi->igi_rv;
2986 			}
2987 			IGMP_INET_PRINTF(inm->inm_addr,
2988 			    ("%s: Leaving %s/%s with %d "
2989 			    "pending retransmissions.\n", __func__,
2990 			    _igmp_inet_buf, if_name(inm->inm_ifp),
2991 			    inm->inm_scrv));
2992 			if (inm->inm_scrv == 0) {
2993 				inm->inm_state = IGMP_NOT_MEMBER;
2994 				inm->inm_sctimer = 0;
2995 			} else {
2996 				int retval;
2997 				/*
2998 				 * Stick around in the in_multihead list;
2999 				 * the final detach will be issued by
3000 				 * igmp_v3_process_group_timers() when
3001 				 * the retransmit timer expires.
3002 				 */
3003 				INM_ADDREF_LOCKED(inm);
3004 				VERIFY(inm->inm_debug & IFD_ATTACHED);
3005 				inm->inm_reqcnt++;
3006 				VERIFY(inm->inm_reqcnt >= 1);
3007 				inm->inm_nrelecnt++;
3008 				VERIFY(inm->inm_nrelecnt != 0);
3009 
3010 				retval = igmp_v3_enqueue_group_record(
3011 					&inm->inm_scq, inm, 1, 0, 0);
3012 				itp->cst = (inm->inm_scq.ifq_len > 0);
3013 				KASSERT(retval != 0,
3014 				    ("%s: enqueue record = %d\n", __func__,
3015 				    retval));
3016 
3017 				inm->inm_state = IGMP_LEAVING_MEMBER;
3018 				inm->inm_sctimer = 1;
3019 				itp->sct = 1;
3020 				syncstates = 0;
3021 			}
3022 		}
3023 		IGI_UNLOCK(igi);
3024 		break;
3025 	case IGMP_LAZY_MEMBER:
3026 	case IGMP_SLEEPING_MEMBER:
3027 	case IGMP_AWAKENING_MEMBER:
3028 		/* Our reports are suppressed; do nothing. */
3029 		break;
3030 	}
3031 
3032 	if (syncstates) {
3033 		inm_commit(inm);
3034 		IGMP_INET_PRINTF(inm->inm_addr,
3035 		    ("%s: T1 -> T0 for %s/%s\n", __func__,
3036 		    _igmp_inet_buf, if_name(inm->inm_ifp)));
3037 		inm->inm_st[1].iss_fmode = MCAST_UNDEFINED;
3038 		IGMP_INET_PRINTF(inm->inm_addr,
3039 		    ("%s: T1 now MCAST_UNDEFINED for %s/%s\n",
3040 		    __func__, _igmp_inet_buf, if_name(inm->inm_ifp)));
3041 	}
3042 }
3043 
3044 /*
3045  * Enqueue an IGMPv3 group record to the given output queue.
3046  *
3047  * XXX This function could do with having the allocation code
3048  * split out, and the multiple-tree-walks coalesced into a single
3049  * routine as has been done in igmp_v3_enqueue_filter_change().
3050  *
3051  * If is_state_change is zero, a current-state record is appended.
3052  * If is_state_change is non-zero, a state-change report is appended.
3053  *
3054  * If is_group_query is non-zero, an mbuf packet chain is allocated.
3055  * If is_group_query is zero, and if there is a packet with free space
3056  * at the tail of the queue, it will be appended to providing there
3057  * is enough free space.
3058  * Otherwise a new mbuf packet chain is allocated.
3059  *
3060  * If is_source_query is non-zero, each source is checked to see if
3061  * it was recorded for a Group-Source query, and will be omitted if
3062  * it is not both in-mode and recorded.
3063  *
3064  * The function will attempt to allocate leading space in the packet
3065  * for the IP/IGMP header to be prepended without fragmenting the chain.
3066  *
3067  * If successful the size of all data appended to the queue is returned,
3068  * otherwise an error code less than zero is returned, or zero if
3069  * no record(s) were appended.
3070  */
3071 static int
igmp_v3_enqueue_group_record(struct ifqueue * ifq,struct in_multi * inm,const int is_state_change,const int is_group_query,const int is_source_query)3072 igmp_v3_enqueue_group_record(struct ifqueue *ifq, struct in_multi *inm,
3073     const int is_state_change, const int is_group_query,
3074     const int is_source_query)
3075 {
3076 	struct igmp_grouprec     ig;
3077 	struct igmp_grouprec    *pig;
3078 	struct ifnet            *ifp;
3079 	struct ip_msource       *ims, *nims;
3080 	struct mbuf             *m0, *m, *md;
3081 	int                      error, is_filter_list_change;
3082 	int                      minrec0len, m0srcs, nbytes, off;
3083 	uint16_t                 msrcs;
3084 	int                      record_has_sources;
3085 	int                      now;
3086 	int                      type;
3087 	in_addr_t                naddr;
3088 	uint16_t                 mode;
3089 	u_int16_t                ig_numsrc;
3090 
3091 	INM_LOCK_ASSERT_HELD(inm);
3092 	IGI_LOCK_ASSERT_HELD(inm->inm_igi);
3093 
3094 	error = 0;
3095 	ifp = inm->inm_ifp;
3096 	is_filter_list_change = 0;
3097 	m = NULL;
3098 	m0 = NULL;
3099 	m0srcs = 0;
3100 	msrcs = 0;
3101 	nbytes = 0;
3102 	nims = NULL;
3103 	record_has_sources = 1;
3104 	pig = NULL;
3105 	type = IGMP_DO_NOTHING;
3106 	mode = inm->inm_st[1].iss_fmode;
3107 
3108 	/*
3109 	 * If we did not transition out of ASM mode during t0->t1,
3110 	 * and there are no source nodes to process, we can skip
3111 	 * the generation of source records.
3112 	 */
3113 	if (inm->inm_st[0].iss_asm > 0 && inm->inm_st[1].iss_asm > 0 &&
3114 	    inm->inm_nsrc == 0) {
3115 		record_has_sources = 0;
3116 	}
3117 
3118 	if (is_state_change) {
3119 		/*
3120 		 * Queue a state change record.
3121 		 * If the mode did not change, and there are non-ASM
3122 		 * listeners or source filters present,
3123 		 * we potentially need to issue two records for the group.
3124 		 * If we are transitioning to MCAST_UNDEFINED, we need
3125 		 * not send any sources.
3126 		 * If there are ASM listeners, and there was no filter
3127 		 * mode transition of any kind, do nothing.
3128 		 */
3129 		if (mode != inm->inm_st[0].iss_fmode) {
3130 			if (mode == MCAST_EXCLUDE) {
3131 				IGMP_PRINTF(("%s: change to EXCLUDE\n",
3132 				    __func__));
3133 				type = IGMP_CHANGE_TO_EXCLUDE_MODE;
3134 			} else {
3135 				IGMP_PRINTF(("%s: change to INCLUDE\n",
3136 				    __func__));
3137 				type = IGMP_CHANGE_TO_INCLUDE_MODE;
3138 				if (mode == MCAST_UNDEFINED) {
3139 					record_has_sources = 0;
3140 				}
3141 			}
3142 		} else {
3143 			if (record_has_sources) {
3144 				is_filter_list_change = 1;
3145 			} else {
3146 				type = IGMP_DO_NOTHING;
3147 			}
3148 		}
3149 	} else {
3150 		/*
3151 		 * Queue a current state record.
3152 		 */
3153 		if (mode == MCAST_EXCLUDE) {
3154 			type = IGMP_MODE_IS_EXCLUDE;
3155 		} else if (mode == MCAST_INCLUDE) {
3156 			type = IGMP_MODE_IS_INCLUDE;
3157 			VERIFY(inm->inm_st[1].iss_asm == 0);
3158 		}
3159 	}
3160 
3161 	/*
3162 	 * Generate the filter list changes using a separate function.
3163 	 */
3164 	if (is_filter_list_change) {
3165 		return igmp_v3_enqueue_filter_change(ifq, inm);
3166 	}
3167 
3168 	if (type == IGMP_DO_NOTHING) {
3169 		IGMP_INET_PRINTF(inm->inm_addr,
3170 		    ("%s: nothing to do for %s/%s\n",
3171 		    __func__, _igmp_inet_buf,
3172 		    if_name(inm->inm_ifp)));
3173 		return 0;
3174 	}
3175 
3176 	/*
3177 	 * If any sources are present, we must be able to fit at least
3178 	 * one in the trailing space of the tail packet's mbuf,
3179 	 * ideally more.
3180 	 */
3181 	minrec0len = sizeof(struct igmp_grouprec);
3182 	if (record_has_sources) {
3183 		minrec0len += sizeof(in_addr_t);
3184 	}
3185 
3186 	IGMP_INET_PRINTF(inm->inm_addr,
3187 	    ("%s: queueing %s for %s/%s\n", __func__,
3188 	    igmp_rec_type_to_str(type), _igmp_inet_buf,
3189 	    if_name(inm->inm_ifp)));
3190 
3191 	/*
3192 	 * Check if we have a packet in the tail of the queue for this
3193 	 * group into which the first group record for this group will fit.
3194 	 * Otherwise allocate a new packet.
3195 	 * Always allocate leading space for IP+RA_OPT+IGMP+REPORT.
3196 	 * Note: Group records for G/GSR query responses MUST be sent
3197 	 * in their own packet.
3198 	 */
3199 	m0 = ifq->ifq_tail;
3200 	if (!is_group_query &&
3201 	    m0 != NULL &&
3202 	    (m0->m_pkthdr.vt_nrecs + 1 <= IGMP_V3_REPORT_MAXRECS) &&
3203 	    (m0->m_pkthdr.len + minrec0len) <
3204 	    (ifp->if_mtu - IGMP_LEADINGSPACE)) {
3205 		m0srcs = (ifp->if_mtu - m0->m_pkthdr.len -
3206 		    sizeof(struct igmp_grouprec)) / sizeof(in_addr_t);
3207 		m = m0;
3208 		IGMP_PRINTF(("%s: use existing packet\n", __func__));
3209 	} else {
3210 		if (IF_QFULL(ifq)) {
3211 			IGMP_PRINTF(("%s: outbound queue full\n", __func__));
3212 			return -ENOMEM;
3213 		}
3214 		m = NULL;
3215 		m0srcs = (ifp->if_mtu - IGMP_LEADINGSPACE -
3216 		    sizeof(struct igmp_grouprec)) / sizeof(in_addr_t);
3217 		if (!is_state_change && !is_group_query) {
3218 			m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
3219 			if (m) {
3220 				m->m_data += IGMP_LEADINGSPACE;
3221 			}
3222 		}
3223 		if (m == NULL) {
3224 			m = m_gethdr(M_DONTWAIT, MT_DATA);
3225 			if (m) {
3226 				MH_ALIGN(m, IGMP_LEADINGSPACE);
3227 			}
3228 		}
3229 		if (m == NULL) {
3230 			return -ENOMEM;
3231 		}
3232 
3233 		igmp_save_context(m, ifp);
3234 
3235 		IGMP_PRINTF(("%s: allocated first packet\n", __func__));
3236 	}
3237 
3238 	/*
3239 	 * Append group record.
3240 	 * If we have sources, we don't know how many yet.
3241 	 */
3242 	ig.ig_type = (u_char)type;
3243 	ig.ig_datalen = 0;
3244 	ig.ig_numsrc = 0;
3245 	ig.ig_group = inm->inm_addr;
3246 	if (!m_append(m, sizeof(struct igmp_grouprec), (void *)&ig)) {
3247 		if (m != m0) {
3248 			m_freem(m);
3249 		}
3250 		IGMP_PRINTF(("%s: m_append() failed.\n", __func__));
3251 		return -ENOMEM;
3252 	}
3253 	nbytes += sizeof(struct igmp_grouprec);
3254 
3255 	/*
3256 	 * Append as many sources as will fit in the first packet.
3257 	 * If we are appending to a new packet, the chain allocation
3258 	 * may potentially use clusters; use m_getptr() in this case.
3259 	 * If we are appending to an existing packet, we need to obtain
3260 	 * a pointer to the group record after m_append(), in case a new
3261 	 * mbuf was allocated.
3262 	 * Only append sources which are in-mode at t1. If we are
3263 	 * transitioning to MCAST_UNDEFINED state on the group, do not
3264 	 * include source entries.
3265 	 * Only report recorded sources in our filter set when responding
3266 	 * to a group-source query.
3267 	 */
3268 	if (record_has_sources) {
3269 		if (m == m0) {
3270 			md = m_last(m);
3271 			pig = (struct igmp_grouprec *)(void *)
3272 			    (mtod(md, uint8_t *) + md->m_len - nbytes);
3273 		} else {
3274 			md = m_getptr(m, 0, &off);
3275 			pig = (struct igmp_grouprec *)(void *)
3276 			    (mtod(md, uint8_t *) + off);
3277 		}
3278 		msrcs = 0;
3279 		RB_FOREACH_SAFE(ims, ip_msource_tree, &inm->inm_srcs, nims) {
3280 #ifdef IGMP_DEBUG
3281 			char buf[MAX_IPv4_STR_LEN];
3282 
3283 			inet_ntop_haddr(ims->ims_haddr, buf, sizeof(buf));
3284 			IGMP_PRINTF(("%s: visit node %s\n", __func__, buf));
3285 #endif
3286 			now = ims_get_mode(inm, ims, 1);
3287 			IGMP_PRINTF(("%s: node is %d\n", __func__, now));
3288 			if ((now != mode) ||
3289 			    (now == mode && mode == MCAST_UNDEFINED)) {
3290 				IGMP_PRINTF(("%s: skip node\n", __func__));
3291 				continue;
3292 			}
3293 			if (is_source_query && ims->ims_stp == 0) {
3294 				IGMP_PRINTF(("%s: skip unrecorded node\n",
3295 				    __func__));
3296 				continue;
3297 			}
3298 			IGMP_PRINTF(("%s: append node\n", __func__));
3299 			naddr = htonl(ims->ims_haddr);
3300 			if (!m_append(m, sizeof(in_addr_t), (void *)&naddr)) {
3301 				if (m != m0) {
3302 					m_freem(m);
3303 				}
3304 				IGMP_PRINTF(("%s: m_append() failed.\n",
3305 				    __func__));
3306 				return -ENOMEM;
3307 			}
3308 			nbytes += sizeof(in_addr_t);
3309 			++msrcs;
3310 			if (msrcs == m0srcs) {
3311 				break;
3312 			}
3313 		}
3314 		IGMP_PRINTF(("%s: msrcs is %d this packet\n", __func__,
3315 		    msrcs));
3316 		ig_numsrc = htons(msrcs);
3317 		bcopy(&ig_numsrc, &pig->ig_numsrc, sizeof(ig_numsrc));
3318 		nbytes += (msrcs * sizeof(in_addr_t));
3319 	}
3320 
3321 	if (is_source_query && msrcs == 0) {
3322 		IGMP_PRINTF(("%s: no recorded sources to report\n", __func__));
3323 		if (m != m0) {
3324 			m_freem(m);
3325 		}
3326 		return 0;
3327 	}
3328 
3329 	/*
3330 	 * We are good to go with first packet.
3331 	 */
3332 	if (m != m0) {
3333 		IGMP_PRINTF(("%s: enqueueing first packet\n", __func__));
3334 		m->m_pkthdr.vt_nrecs = 1;
3335 		IF_ENQUEUE(ifq, m);
3336 	} else {
3337 		m->m_pkthdr.vt_nrecs++;
3338 	}
3339 	/*
3340 	 * No further work needed if no source list in packet(s).
3341 	 */
3342 	if (!record_has_sources) {
3343 		return nbytes;
3344 	}
3345 
3346 	/*
3347 	 * Whilst sources remain to be announced, we need to allocate
3348 	 * a new packet and fill out as many sources as will fit.
3349 	 * Always try for a cluster first.
3350 	 */
3351 	while (nims != NULL) {
3352 		if (IF_QFULL(ifq)) {
3353 			IGMP_PRINTF(("%s: outbound queue full\n", __func__));
3354 			return -ENOMEM;
3355 		}
3356 		m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
3357 		if (m) {
3358 			m->m_data += IGMP_LEADINGSPACE;
3359 		}
3360 		if (m == NULL) {
3361 			m = m_gethdr(M_DONTWAIT, MT_DATA);
3362 			if (m) {
3363 				MH_ALIGN(m, IGMP_LEADINGSPACE);
3364 			}
3365 		}
3366 		if (m == NULL) {
3367 			return -ENOMEM;
3368 		}
3369 		igmp_save_context(m, ifp);
3370 		md = m_getptr(m, 0, &off);
3371 		pig = (struct igmp_grouprec *)(void *)
3372 		    (mtod(md, uint8_t *) + off);
3373 		IGMP_PRINTF(("%s: allocated next packet\n", __func__));
3374 
3375 		if (!m_append(m, sizeof(struct igmp_grouprec), (void *)&ig)) {
3376 			if (m != m0) {
3377 				m_freem(m);
3378 			}
3379 			IGMP_PRINTF(("%s: m_append() failed.\n", __func__));
3380 			return -ENOMEM;
3381 		}
3382 		m->m_pkthdr.vt_nrecs = 1;
3383 		nbytes += sizeof(struct igmp_grouprec);
3384 
3385 		m0srcs = (ifp->if_mtu - IGMP_LEADINGSPACE -
3386 		    sizeof(struct igmp_grouprec)) / sizeof(in_addr_t);
3387 
3388 		msrcs = 0;
3389 		RB_FOREACH_FROM(ims, ip_msource_tree, nims) {
3390 #ifdef IGMP_DEBUG
3391 			char buf[MAX_IPv4_STR_LEN];
3392 
3393 			inet_ntop_haddr(ims->ims_haddr, buf, sizeof(buf));
3394 			IGMP_PRINTF(("%s: visit node %s\n", __func__, buf));
3395 #endif
3396 			now = ims_get_mode(inm, ims, 1);
3397 			if ((now != mode) ||
3398 			    (now == mode && mode == MCAST_UNDEFINED)) {
3399 				IGMP_PRINTF(("%s: skip node\n", __func__));
3400 				continue;
3401 			}
3402 			if (is_source_query && ims->ims_stp == 0) {
3403 				IGMP_PRINTF(("%s: skip unrecorded node\n",
3404 				    __func__));
3405 				continue;
3406 			}
3407 			IGMP_PRINTF(("%s: append node\n", __func__));
3408 			naddr = htonl(ims->ims_haddr);
3409 			if (!m_append(m, sizeof(in_addr_t), (void *)&naddr)) {
3410 				if (m != m0) {
3411 					m_freem(m);
3412 				}
3413 				IGMP_PRINTF(("%s: m_append() failed.\n",
3414 				    __func__));
3415 				return -ENOMEM;
3416 			}
3417 			++msrcs;
3418 			if (msrcs == m0srcs) {
3419 				break;
3420 			}
3421 		}
3422 		ig_numsrc = htons(msrcs);
3423 		bcopy(&ig_numsrc, &pig->ig_numsrc, sizeof(ig_numsrc));
3424 		nbytes += (msrcs * sizeof(in_addr_t));
3425 
3426 		IGMP_PRINTF(("%s: enqueueing next packet\n", __func__));
3427 		IF_ENQUEUE(ifq, m);
3428 	}
3429 
3430 	return nbytes;
3431 }
3432 
3433 /*
3434  * Type used to mark record pass completion.
3435  * We exploit the fact we can cast to this easily from the
3436  * current filter modes on each ip_msource node.
3437  */
3438 typedef enum {
3439 	REC_NONE = 0x00,        /* MCAST_UNDEFINED */
3440 	REC_ALLOW = 0x01,       /* MCAST_INCLUDE */
3441 	REC_BLOCK = 0x02,       /* MCAST_EXCLUDE */
3442 	REC_FULL = REC_ALLOW | REC_BLOCK
3443 } rectype_t;
3444 
3445 /*
3446  * Enqueue an IGMPv3 filter list change to the given output queue.
3447  *
3448  * Source list filter state is held in an RB-tree. When the filter list
3449  * for a group is changed without changing its mode, we need to compute
3450  * the deltas between T0 and T1 for each source in the filter set,
3451  * and enqueue the appropriate ALLOW_NEW/BLOCK_OLD records.
3452  *
3453  * As we may potentially queue two record types, and the entire R-B tree
3454  * needs to be walked at once, we break this out into its own function
3455  * so we can generate a tightly packed queue of packets.
3456  *
3457  * XXX This could be written to only use one tree walk, although that makes
3458  * serializing into the mbuf chains a bit harder. For now we do two walks
3459  * which makes things easier on us, and it may or may not be harder on
3460  * the L2 cache.
3461  *
3462  * If successful the size of all data appended to the queue is returned,
3463  * otherwise an error code less than zero is returned, or zero if
3464  * no record(s) were appended.
3465  */
3466 static int
igmp_v3_enqueue_filter_change(struct ifqueue * ifq,struct in_multi * inm)3467 igmp_v3_enqueue_filter_change(struct ifqueue *ifq, struct in_multi *inm)
3468 {
3469 	static const int MINRECLEN =
3470 	    sizeof(struct igmp_grouprec) + sizeof(in_addr_t);
3471 	struct ifnet            *ifp;
3472 	struct igmp_grouprec     ig;
3473 	struct igmp_grouprec    *pig;
3474 	struct ip_msource       *ims, *nims;
3475 	struct mbuf             *m, *m0, *md;
3476 	in_addr_t                naddr;
3477 	int                      m0srcs, nbytes, npbytes, off, schanged;
3478 	uint16_t                 rsrcs;
3479 	int                      nallow, nblock;
3480 	uint16_t                 mode;
3481 	uint8_t                  now, then;
3482 	rectype_t                crt, drt, nrt;
3483 	u_int16_t                ig_numsrc;
3484 
3485 	INM_LOCK_ASSERT_HELD(inm);
3486 
3487 	if (inm->inm_nsrc == 0 ||
3488 	    (inm->inm_st[0].iss_asm > 0 && inm->inm_st[1].iss_asm > 0)) {
3489 		return 0;
3490 	}
3491 
3492 	ifp = inm->inm_ifp;                     /* interface */
3493 	mode = inm->inm_st[1].iss_fmode;        /* filter mode at t1 */
3494 	crt = REC_NONE; /* current group record type */
3495 	drt = REC_NONE; /* mask of completed group record types */
3496 	nrt = REC_NONE; /* record type for current node */
3497 	m0srcs = 0;     /* # source which will fit in current mbuf chain */
3498 	nbytes = 0;     /* # of bytes appended to group's state-change queue */
3499 	npbytes = 0;    /* # of bytes appended this packet */
3500 	rsrcs = 0;      /* # sources encoded in current record */
3501 	schanged = 0;   /* # nodes encoded in overall filter change */
3502 	nallow = 0;     /* # of source entries in ALLOW_NEW */
3503 	nblock = 0;     /* # of source entries in BLOCK_OLD */
3504 	nims = NULL;    /* next tree node pointer */
3505 
3506 	/*
3507 	 * For each possible filter record mode.
3508 	 * The first kind of source we encounter tells us which
3509 	 * is the first kind of record we start appending.
3510 	 * If a node transitioned to UNDEFINED at t1, its mode is treated
3511 	 * as the inverse of the group's filter mode.
3512 	 */
3513 	while (drt != REC_FULL) {
3514 		do {
3515 			m0 = ifq->ifq_tail;
3516 			if (m0 != NULL &&
3517 			    (m0->m_pkthdr.vt_nrecs + 1 <=
3518 			    IGMP_V3_REPORT_MAXRECS) &&
3519 			    (m0->m_pkthdr.len + MINRECLEN) <
3520 			    (ifp->if_mtu - IGMP_LEADINGSPACE)) {
3521 				m = m0;
3522 				m0srcs = (ifp->if_mtu - m0->m_pkthdr.len -
3523 				    sizeof(struct igmp_grouprec)) /
3524 				    sizeof(in_addr_t);
3525 				IGMP_PRINTF(("%s: use previous packet\n",
3526 				    __func__));
3527 			} else {
3528 				m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
3529 				if (m) {
3530 					m->m_data += IGMP_LEADINGSPACE;
3531 				}
3532 				if (m == NULL) {
3533 					m = m_gethdr(M_DONTWAIT, MT_DATA);
3534 					if (m) {
3535 						MH_ALIGN(m, IGMP_LEADINGSPACE);
3536 					}
3537 				}
3538 				if (m == NULL) {
3539 					IGMP_PRINTF(("%s: m_get*() failed\n",
3540 					    __func__));
3541 					return -ENOMEM;
3542 				}
3543 				m->m_pkthdr.vt_nrecs = 0;
3544 				igmp_save_context(m, ifp);
3545 				m0srcs = (ifp->if_mtu - IGMP_LEADINGSPACE -
3546 				    sizeof(struct igmp_grouprec)) /
3547 				    sizeof(in_addr_t);
3548 				npbytes = 0;
3549 				IGMP_PRINTF(("%s: allocated new packet\n",
3550 				    __func__));
3551 			}
3552 			/*
3553 			 * Append the IGMP group record header to the
3554 			 * current packet's data area.
3555 			 * Recalculate pointer to free space for next
3556 			 * group record, in case m_append() allocated
3557 			 * a new mbuf or cluster.
3558 			 */
3559 			memset(&ig, 0, sizeof(ig));
3560 			ig.ig_group = inm->inm_addr;
3561 			if (!m_append(m, sizeof(ig), (void *)&ig)) {
3562 				if (m != m0) {
3563 					m_freem(m);
3564 				}
3565 				IGMP_PRINTF(("%s: m_append() failed\n",
3566 				    __func__));
3567 				return -ENOMEM;
3568 			}
3569 			npbytes += sizeof(struct igmp_grouprec);
3570 			if (m != m0) {
3571 				/* new packet; offset in c hain */
3572 				md = m_getptr(m, npbytes -
3573 				    sizeof(struct igmp_grouprec), &off);
3574 				pig = (struct igmp_grouprec *)(void *)(mtod(md,
3575 				    uint8_t *) + off);
3576 			} else {
3577 				/* current packet; offset from last append */
3578 				md = m_last(m);
3579 				pig = (struct igmp_grouprec *)(void *)(mtod(md,
3580 				    uint8_t *) + md->m_len -
3581 				    sizeof(struct igmp_grouprec));
3582 			}
3583 			/*
3584 			 * Begin walking the tree for this record type
3585 			 * pass, or continue from where we left off
3586 			 * previously if we had to allocate a new packet.
3587 			 * Only report deltas in-mode at t1.
3588 			 * We need not report included sources as allowed
3589 			 * if we are in inclusive mode on the group,
3590 			 * however the converse is not true.
3591 			 */
3592 			rsrcs = 0;
3593 			if (nims == NULL) {
3594 				nims = RB_MIN(ip_msource_tree, &inm->inm_srcs);
3595 			}
3596 			RB_FOREACH_FROM(ims, ip_msource_tree, nims) {
3597 #ifdef IGMP_DEBUG
3598 				char buf[MAX_IPv4_STR_LEN];
3599 
3600 				inet_ntop_haddr(ims->ims_haddr, buf, sizeof(buf));
3601 				IGMP_PRINTF(("%s: visit node %s\n", __func__, buf));
3602 #endif
3603 				now = ims_get_mode(inm, ims, 1);
3604 				then = ims_get_mode(inm, ims, 0);
3605 				IGMP_PRINTF(("%s: mode: t0 %d, t1 %d\n",
3606 				    __func__, then, now));
3607 				if (now == then) {
3608 					IGMP_PRINTF(("%s: skip unchanged\n",
3609 					    __func__));
3610 					continue;
3611 				}
3612 				if (mode == MCAST_EXCLUDE &&
3613 				    now == MCAST_INCLUDE) {
3614 					IGMP_PRINTF(("%s: skip IN src on EX "
3615 					    "group\n", __func__));
3616 					continue;
3617 				}
3618 				nrt = (rectype_t)now;
3619 				if (nrt == REC_NONE) {
3620 					nrt = (rectype_t)(~mode & REC_FULL);
3621 				}
3622 				if (schanged++ == 0) {
3623 					crt = nrt;
3624 				} else if (crt != nrt) {
3625 					continue;
3626 				}
3627 				naddr = htonl(ims->ims_haddr);
3628 				if (!m_append(m, sizeof(in_addr_t),
3629 				    (void *)&naddr)) {
3630 					if (m != m0) {
3631 						m_freem(m);
3632 					}
3633 					IGMP_PRINTF(("%s: m_append() failed\n",
3634 					    __func__));
3635 					return -ENOMEM;
3636 				}
3637 				nallow += !!(crt == REC_ALLOW);
3638 				nblock += !!(crt == REC_BLOCK);
3639 				if (++rsrcs == m0srcs) {
3640 					break;
3641 				}
3642 			}
3643 			/*
3644 			 * If we did not append any tree nodes on this
3645 			 * pass, back out of allocations.
3646 			 */
3647 			if (rsrcs == 0) {
3648 				npbytes -= sizeof(struct igmp_grouprec);
3649 				if (m != m0) {
3650 					IGMP_PRINTF(("%s: m_free(m)\n",
3651 					    __func__));
3652 					m_freem(m);
3653 				} else {
3654 					IGMP_PRINTF(("%s: m_adj(m, -ig)\n",
3655 					    __func__));
3656 					m_adj(m, -((int)sizeof(
3657 						    struct igmp_grouprec)));
3658 				}
3659 				continue;
3660 			}
3661 			npbytes += (rsrcs * sizeof(in_addr_t));
3662 			if (crt == REC_ALLOW) {
3663 				pig->ig_type = IGMP_ALLOW_NEW_SOURCES;
3664 			} else if (crt == REC_BLOCK) {
3665 				pig->ig_type = IGMP_BLOCK_OLD_SOURCES;
3666 			}
3667 			ig_numsrc = htons(rsrcs);
3668 			bcopy(&ig_numsrc, &pig->ig_numsrc, sizeof(ig_numsrc));
3669 			/*
3670 			 * Count the new group record, and enqueue this
3671 			 * packet if it wasn't already queued.
3672 			 */
3673 			m->m_pkthdr.vt_nrecs++;
3674 			if (m != m0) {
3675 				IF_ENQUEUE(ifq, m);
3676 			}
3677 			nbytes += npbytes;
3678 		} while (nims != NULL);
3679 		drt |= crt;
3680 		crt = (~crt & REC_FULL);
3681 	}
3682 
3683 	IGMP_PRINTF(("%s: queued %d ALLOW_NEW, %d BLOCK_OLD\n", __func__,
3684 	    nallow, nblock));
3685 
3686 	return nbytes;
3687 }
3688 
3689 static int
igmp_v3_merge_state_changes(struct in_multi * inm,struct ifqueue * ifscq)3690 igmp_v3_merge_state_changes(struct in_multi *inm, struct ifqueue *ifscq)
3691 {
3692 	struct ifqueue  *gq;
3693 	struct mbuf     *m;             /* pending state-change */
3694 	struct mbuf     *m0;            /* copy of pending state-change */
3695 	struct mbuf     *mt;            /* last state-change in packet */
3696 	struct mbuf     *n;
3697 	int              docopy, domerge;
3698 	u_int            recslen;
3699 
3700 	INM_LOCK_ASSERT_HELD(inm);
3701 
3702 	docopy = 0;
3703 	domerge = 0;
3704 	recslen = 0;
3705 
3706 	/*
3707 	 * If there are further pending retransmissions, make a writable
3708 	 * copy of each queued state-change message before merging.
3709 	 */
3710 	if (inm->inm_scrv > 0) {
3711 		docopy = 1;
3712 	}
3713 
3714 	gq = &inm->inm_scq;
3715 #ifdef IGMP_DEBUG
3716 	if (gq->ifq_head == NULL) {
3717 		IGMP_PRINTF(("%s: WARNING: queue for inm 0x%llx is empty\n",
3718 		    __func__, (uint64_t)VM_KERNEL_ADDRPERM(inm)));
3719 	}
3720 #endif
3721 
3722 	/*
3723 	 * Use IF_REMQUEUE() instead of IF_DEQUEUE() below, since the
3724 	 * packet might not always be at the head of the ifqueue.
3725 	 */
3726 	m = gq->ifq_head;
3727 	while (m != NULL) {
3728 		/*
3729 		 * Only merge the report into the current packet if
3730 		 * there is sufficient space to do so; an IGMPv3 report
3731 		 * packet may only contain 65,535 group records.
3732 		 * Always use a simple mbuf chain concatentation to do this,
3733 		 * as large state changes for single groups may have
3734 		 * allocated clusters.
3735 		 */
3736 		domerge = 0;
3737 		mt = ifscq->ifq_tail;
3738 		if (mt != NULL) {
3739 			recslen = m_length(m);
3740 
3741 			if ((mt->m_pkthdr.vt_nrecs +
3742 			    m->m_pkthdr.vt_nrecs <=
3743 			    IGMP_V3_REPORT_MAXRECS) &&
3744 			    (mt->m_pkthdr.len + recslen <=
3745 			    (inm->inm_ifp->if_mtu - IGMP_LEADINGSPACE))) {
3746 				domerge = 1;
3747 			}
3748 		}
3749 
3750 		if (!domerge && IF_QFULL(gq)) {
3751 			IGMP_PRINTF(("%s: outbound queue full, skipping whole "
3752 			    "packet 0x%llx\n", __func__,
3753 			    (uint64_t)VM_KERNEL_ADDRPERM(m)));
3754 			n = m->m_nextpkt;
3755 			if (!docopy) {
3756 				IF_REMQUEUE(gq, m);
3757 				m_freem(m);
3758 			}
3759 			m = n;
3760 			continue;
3761 		}
3762 
3763 		if (!docopy) {
3764 			IGMP_PRINTF(("%s: dequeueing 0x%llx\n", __func__,
3765 			    (uint64_t)VM_KERNEL_ADDRPERM(m)));
3766 			n = m->m_nextpkt;
3767 			IF_REMQUEUE(gq, m);
3768 			m0 = m;
3769 			m = n;
3770 		} else {
3771 			IGMP_PRINTF(("%s: copying 0x%llx\n", __func__,
3772 			    (uint64_t)VM_KERNEL_ADDRPERM(m)));
3773 			m0 = m_dup(m, M_NOWAIT);
3774 			if (m0 == NULL) {
3775 				return ENOMEM;
3776 			}
3777 			m0->m_nextpkt = NULL;
3778 			m = m->m_nextpkt;
3779 		}
3780 
3781 		if (!domerge) {
3782 			IGMP_PRINTF(("%s: queueing 0x%llx to ifscq 0x%llx)\n",
3783 			    __func__, (uint64_t)VM_KERNEL_ADDRPERM(m0),
3784 			    (uint64_t)VM_KERNEL_ADDRPERM(ifscq)));
3785 			IF_ENQUEUE(ifscq, m0);
3786 		} else {
3787 			struct mbuf *mtl;       /* last mbuf of packet mt */
3788 
3789 			IGMP_PRINTF(("%s: merging 0x%llx with ifscq tail "
3790 			    "0x%llx)\n", __func__,
3791 			    (uint64_t)VM_KERNEL_ADDRPERM(m0),
3792 			    (uint64_t)VM_KERNEL_ADDRPERM(mt)));
3793 
3794 			mtl = m_last(mt);
3795 			m0->m_flags &= ~M_PKTHDR;
3796 			mt->m_pkthdr.len += recslen;
3797 			mt->m_pkthdr.vt_nrecs +=
3798 			    m0->m_pkthdr.vt_nrecs;
3799 
3800 			mtl->m_next = m0;
3801 		}
3802 	}
3803 
3804 	return 0;
3805 }
3806 
3807 /*
3808  * Respond to a pending IGMPv3 General Query.
3809  */
3810 static uint32_t
igmp_v3_dispatch_general_query(struct igmp_ifinfo * igi)3811 igmp_v3_dispatch_general_query(struct igmp_ifinfo *igi)
3812 {
3813 	struct ifnet            *ifp;
3814 	struct in_multi         *inm;
3815 	struct in_multistep     step;
3816 	int                      retval, loop;
3817 
3818 	IGI_LOCK_ASSERT_HELD(igi);
3819 
3820 	VERIFY(igi->igi_version == IGMP_VERSION_3);
3821 
3822 	ifp = igi->igi_ifp;
3823 	IGI_UNLOCK(igi);
3824 
3825 	in_multihead_lock_shared();
3826 	IN_FIRST_MULTI(step, inm);
3827 	while (inm != NULL) {
3828 		INM_LOCK(inm);
3829 		if (inm->inm_ifp != ifp) {
3830 			goto next;
3831 		}
3832 
3833 		switch (inm->inm_state) {
3834 		case IGMP_NOT_MEMBER:
3835 		case IGMP_SILENT_MEMBER:
3836 			break;
3837 		case IGMP_REPORTING_MEMBER:
3838 		case IGMP_IDLE_MEMBER:
3839 		case IGMP_LAZY_MEMBER:
3840 		case IGMP_SLEEPING_MEMBER:
3841 		case IGMP_AWAKENING_MEMBER:
3842 			inm->inm_state = IGMP_REPORTING_MEMBER;
3843 			IGI_LOCK(igi);
3844 			retval = igmp_v3_enqueue_group_record(&igi->igi_gq,
3845 			    inm, 0, 0, 0);
3846 			IGI_UNLOCK(igi);
3847 			IGMP_PRINTF(("%s: enqueue record = %d\n",
3848 			    __func__, retval));
3849 			break;
3850 		case IGMP_G_QUERY_PENDING_MEMBER:
3851 		case IGMP_SG_QUERY_PENDING_MEMBER:
3852 		case IGMP_LEAVING_MEMBER:
3853 			break;
3854 		}
3855 next:
3856 		INM_UNLOCK(inm);
3857 		IN_NEXT_MULTI(step, inm);
3858 	}
3859 	in_multihead_lock_done();
3860 
3861 	IGI_LOCK(igi);
3862 	loop = (igi->igi_flags & IGIF_LOOPBACK) ? 1 : 0;
3863 	igmp_dispatch_queue(igi, &igi->igi_gq, IGMP_MAX_RESPONSE_BURST,
3864 	    loop);
3865 	IGI_LOCK_ASSERT_HELD(igi);
3866 	/*
3867 	 * Slew transmission of bursts over 1 second intervals.
3868 	 */
3869 	if (igi->igi_gq.ifq_head != NULL) {
3870 		igi->igi_v3_timer = 1 + IGMP_RANDOM_DELAY(
3871 			IGMP_RESPONSE_BURST_INTERVAL);
3872 	}
3873 
3874 	return igi->igi_v3_timer;
3875 }
3876 
3877 /*
3878  * Transmit the next pending IGMP message in the output queue.
3879  *
3880  * Must not be called with inm_lock or igi_lock held.
3881  */
3882 static void
igmp_sendpkt(struct mbuf * m)3883 igmp_sendpkt(struct mbuf *m)
3884 {
3885 	struct ip_moptions      *imo;
3886 	struct mbuf             *ipopts, *m0;
3887 	int                     error;
3888 	struct route            ro;
3889 	struct ifnet            *ifp;
3890 
3891 	IGMP_PRINTF(("%s: transmit 0x%llx\n", __func__,
3892 	    (uint64_t)VM_KERNEL_ADDRPERM(m)));
3893 
3894 	ifp = igmp_restore_context(m);
3895 	/*
3896 	 * Check if the ifnet is still attached.
3897 	 */
3898 	if (ifp == NULL || !ifnet_is_attached(ifp, 0)) {
3899 		IGMP_PRINTF(("%s: dropped 0x%llx as ifp went away.\n",
3900 		    __func__, (uint64_t)VM_KERNEL_ADDRPERM(m)));
3901 		m_freem(m);
3902 		OSAddAtomic(1, &ipstat.ips_noroute);
3903 		return;
3904 	}
3905 
3906 	ipopts = igmp_sendra ? m_raopt : NULL;
3907 
3908 	imo = ip_allocmoptions(Z_WAITOK);
3909 	if (imo == NULL) {
3910 		m_freem(m);
3911 		return;
3912 	}
3913 
3914 	imo->imo_multicast_ttl  = 1;
3915 	imo->imo_multicast_vif  = -1;
3916 	imo->imo_multicast_loop = 0;
3917 
3918 	/*
3919 	 * If the user requested that IGMP traffic be explicitly
3920 	 * redirected to the loopback interface (e.g. they are running a
3921 	 * MANET interface and the routing protocol needs to see the
3922 	 * updates), handle this now.
3923 	 */
3924 	if (m->m_flags & M_IGMP_LOOP) {
3925 		imo->imo_multicast_ifp = lo_ifp;
3926 	} else {
3927 		imo->imo_multicast_ifp = ifp;
3928 	}
3929 
3930 	if (m->m_flags & M_IGMPV2) {
3931 		m0 = m;
3932 	} else {
3933 		m0 = igmp_v3_encap_report(ifp, m);
3934 		if (m0 == NULL) {
3935 			/*
3936 			 * If igmp_v3_encap_report() failed, then M_PREPEND()
3937 			 * already freed the original mbuf chain.
3938 			 * This means that we don't have to m_freem(m) here.
3939 			 */
3940 			IGMP_PRINTF(("%s: dropped 0x%llx\n", __func__,
3941 			    (uint64_t)VM_KERNEL_ADDRPERM(m)));
3942 			IMO_REMREF(imo);
3943 			atomic_add_32(&ipstat.ips_odropped, 1);
3944 			return;
3945 		}
3946 	}
3947 
3948 	igmp_scrub_context(m0);
3949 	m->m_flags &= ~(M_PROTOFLAGS | M_IGMP_LOOP);
3950 	m0->m_pkthdr.rcvif = lo_ifp;
3951 
3952 	if (ifp->if_eflags & IFEF_TXSTART) {
3953 		/*
3954 		 * Use control service class if the interface supports
3955 		 * transmit-start model.
3956 		 */
3957 		(void) m_set_service_class(m0, MBUF_SC_CTL);
3958 	}
3959 	bzero(&ro, sizeof(ro));
3960 	error = ip_output(m0, ipopts, &ro, 0, imo, NULL);
3961 	ROUTE_RELEASE(&ro);
3962 
3963 	IMO_REMREF(imo);
3964 
3965 	if (error) {
3966 		IGMP_PRINTF(("%s: ip_output(0x%llx) = %d\n", __func__,
3967 		    (uint64_t)VM_KERNEL_ADDRPERM(m0), error));
3968 		return;
3969 	}
3970 
3971 	IGMPSTAT_INC(igps_snd_reports);
3972 	OIGMPSTAT_INC(igps_snd_reports);
3973 }
3974 /*
3975  * Encapsulate an IGMPv3 report.
3976  *
3977  * The internal mbuf flag M_IGMPV3_HDR is used to indicate that the mbuf
3978  * chain has already had its IP/IGMPv3 header prepended. In this case
3979  * the function will not attempt to prepend; the lengths and checksums
3980  * will however be re-computed.
3981  *
3982  * Returns a pointer to the new mbuf chain head, or NULL if the
3983  * allocation failed.
3984  */
3985 static struct mbuf *
igmp_v3_encap_report(struct ifnet * ifp,struct mbuf * m)3986 igmp_v3_encap_report(struct ifnet *ifp, struct mbuf *m)
3987 {
3988 	struct igmp_report      *igmp;
3989 	struct ip               *ip;
3990 	unsigned int             hdrlen, igmpreclen;
3991 
3992 	VERIFY((m->m_flags & M_PKTHDR));
3993 
3994 	igmpreclen = m_length(m);
3995 	hdrlen = sizeof(struct ip) + sizeof(struct igmp_report);
3996 
3997 	if (m->m_flags & M_IGMPV3_HDR) {
3998 		igmpreclen -= hdrlen;
3999 	} else {
4000 		M_PREPEND(m, hdrlen, M_DONTWAIT, 1);
4001 		if (m == NULL) {
4002 			return NULL;
4003 		}
4004 		m->m_flags |= M_IGMPV3_HDR;
4005 	}
4006 	if (hdrlen + igmpreclen > USHRT_MAX) {
4007 		IGMP_PRINTF(("%s: invalid length %d\n", __func__, hdrlen + igmpreclen));
4008 		m_freem(m);
4009 		return NULL;
4010 	}
4011 
4012 
4013 	IGMP_PRINTF(("%s: igmpreclen is %d\n", __func__, igmpreclen));
4014 
4015 	m->m_data += sizeof(struct ip);
4016 	m->m_len -= sizeof(struct ip);
4017 
4018 	igmp = mtod(m, struct igmp_report *);
4019 	igmp->ir_type = IGMP_v3_HOST_MEMBERSHIP_REPORT;
4020 	igmp->ir_rsv1 = 0;
4021 	igmp->ir_rsv2 = 0;
4022 	igmp->ir_numgrps = htons(m->m_pkthdr.vt_nrecs);
4023 	igmp->ir_cksum = 0;
4024 	igmp->ir_cksum = in_cksum(m, sizeof(struct igmp_report) + igmpreclen);
4025 	m->m_pkthdr.vt_nrecs = 0;
4026 
4027 	m->m_data -= sizeof(struct ip);
4028 	m->m_len += sizeof(struct ip);
4029 
4030 	ip = mtod(m, struct ip *);
4031 	ip->ip_tos = IPTOS_PREC_INTERNETCONTROL;
4032 	ip->ip_len = (u_short)(hdrlen + igmpreclen);
4033 	ip->ip_off = IP_DF;
4034 	ip->ip_p = IPPROTO_IGMP;
4035 	ip->ip_sum = 0;
4036 
4037 	ip->ip_src.s_addr = INADDR_ANY;
4038 
4039 	if (m->m_flags & M_IGMP_LOOP) {
4040 		struct in_ifaddr *ia;
4041 
4042 		IFP_TO_IA(ifp, ia);
4043 		if (ia != NULL) {
4044 			IFA_LOCK(&ia->ia_ifa);
4045 			ip->ip_src = ia->ia_addr.sin_addr;
4046 			IFA_UNLOCK(&ia->ia_ifa);
4047 			IFA_REMREF(&ia->ia_ifa);
4048 		}
4049 	}
4050 
4051 	ip->ip_dst.s_addr = htonl(INADDR_ALLRPTS_GROUP);
4052 
4053 	return m;
4054 }
4055 
4056 #ifdef IGMP_DEBUG
4057 static const char *
igmp_rec_type_to_str(const int type)4058 igmp_rec_type_to_str(const int type)
4059 {
4060 	switch (type) {
4061 	case IGMP_CHANGE_TO_EXCLUDE_MODE:
4062 		return "TO_EX";
4063 	case IGMP_CHANGE_TO_INCLUDE_MODE:
4064 		return "TO_IN";
4065 	case IGMP_MODE_IS_EXCLUDE:
4066 		return "MODE_EX";
4067 	case IGMP_MODE_IS_INCLUDE:
4068 		return "MODE_IN";
4069 	case IGMP_ALLOW_NEW_SOURCES:
4070 		return "ALLOW_NEW";
4071 	case IGMP_BLOCK_OLD_SOURCES:
4072 		return "BLOCK_OLD";
4073 	default:
4074 		break;
4075 	}
4076 	return "unknown";
4077 }
4078 #endif
4079 
4080 void
igmp_init(struct protosw * pp,struct domain * dp)4081 igmp_init(struct protosw *pp, struct domain *dp)
4082 {
4083 #pragma unused(dp)
4084 	static int igmp_initialized = 0;
4085 
4086 	VERIFY((pp->pr_flags & (PR_INITIALIZED | PR_ATTACHED)) == PR_ATTACHED);
4087 
4088 	if (igmp_initialized) {
4089 		return;
4090 	}
4091 	igmp_initialized = 1;
4092 
4093 	IGMP_PRINTF(("%s: initializing\n", __func__));
4094 
4095 	igmp_timers_are_running = 0;
4096 
4097 	LIST_INIT(&igi_head);
4098 	m_raopt = igmp_ra_alloc();
4099 }
4100