1*d4a07e70Sfengbojiang /*-
2*d4a07e70Sfengbojiang  * SPDX-License-Identifier: BSD-3-Clause
3*d4a07e70Sfengbojiang  *
41eaf0ac3Slogwang  * Copyright (c) 1988 Stephen Deering.
51eaf0ac3Slogwang  * Copyright (c) 1992, 1993
61eaf0ac3Slogwang  *	The Regents of the University of California.  All rights reserved.
71eaf0ac3Slogwang  *
81eaf0ac3Slogwang  * This code is derived from software contributed to Berkeley by
91eaf0ac3Slogwang  * Stephen Deering of Stanford University.
101eaf0ac3Slogwang  *
111eaf0ac3Slogwang  * Redistribution and use in source and binary forms, with or without
121eaf0ac3Slogwang  * modification, are permitted provided that the following conditions
131eaf0ac3Slogwang  * are met:
141eaf0ac3Slogwang  * 1. Redistributions of source code must retain the above copyright
151eaf0ac3Slogwang  *    notice, this list of conditions and the following disclaimer.
161eaf0ac3Slogwang  * 2. Redistributions in binary form must reproduce the above copyright
171eaf0ac3Slogwang  *    notice, this list of conditions and the following disclaimer in the
181eaf0ac3Slogwang  *    documentation and/or other materials provided with the distribution.
19*d4a07e70Sfengbojiang  * 3. Neither the name of the University nor the names of its contributors
201eaf0ac3Slogwang  *    may be used to endorse or promote products derived from this software
211eaf0ac3Slogwang  *    without specific prior written permission.
221eaf0ac3Slogwang  *
231eaf0ac3Slogwang  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
241eaf0ac3Slogwang  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
251eaf0ac3Slogwang  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
261eaf0ac3Slogwang  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
271eaf0ac3Slogwang  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
281eaf0ac3Slogwang  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
291eaf0ac3Slogwang  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
301eaf0ac3Slogwang  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
311eaf0ac3Slogwang  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
321eaf0ac3Slogwang  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
331eaf0ac3Slogwang  * SUCH DAMAGE.
341eaf0ac3Slogwang  *
351eaf0ac3Slogwang  *	from: @(#)igmp_var.h	8.1 (Berkeley) 7/19/93
361eaf0ac3Slogwang  * $FreeBSD$
371eaf0ac3Slogwang  */
381eaf0ac3Slogwang 
391eaf0ac3Slogwang #ifndef _NETINET_IGMP_VAR_H_
401eaf0ac3Slogwang #define _NETINET_IGMP_VAR_H_
411eaf0ac3Slogwang 
421eaf0ac3Slogwang /*
431eaf0ac3Slogwang  * Internet Group Management Protocol (IGMP),
441eaf0ac3Slogwang  * implementation-specific definitions.
451eaf0ac3Slogwang  *
461eaf0ac3Slogwang  * Written by Steve Deering, Stanford, May 1988.
471eaf0ac3Slogwang  *
481eaf0ac3Slogwang  * MULTICAST Revision: 3.5.1.3
491eaf0ac3Slogwang  */
501eaf0ac3Slogwang 
511eaf0ac3Slogwang /*
521eaf0ac3Slogwang  * IGMPv3 protocol statistics.
531eaf0ac3Slogwang  */
541eaf0ac3Slogwang struct igmpstat {
551eaf0ac3Slogwang 	/*
561eaf0ac3Slogwang 	 * Structure header (to insulate ABI changes).
57*d4a07e70Sfengbojiang 	 * XXX: unset inside the kernel, exported via sysctl_igmp_stat().
581eaf0ac3Slogwang 	 */
591eaf0ac3Slogwang 	uint32_t igps_version;		/* version of this structure */
601eaf0ac3Slogwang 	uint32_t igps_len;		/* length of this structure */
611eaf0ac3Slogwang 	/*
621eaf0ac3Slogwang 	 * Message statistics.
631eaf0ac3Slogwang 	 */
641eaf0ac3Slogwang 	uint64_t igps_rcv_total;	/* total IGMP messages received */
651eaf0ac3Slogwang 	uint64_t igps_rcv_tooshort;	/* received with too few bytes */
661eaf0ac3Slogwang 	uint64_t igps_rcv_badttl;	/* received with ttl other than 1 */
671eaf0ac3Slogwang 	uint64_t igps_rcv_badsum;	/* received with bad checksum */
681eaf0ac3Slogwang 	/*
691eaf0ac3Slogwang 	 * Query statistics.
701eaf0ac3Slogwang 	 */
711eaf0ac3Slogwang 	uint64_t igps_rcv_v1v2_queries;	/* received IGMPv1/IGMPv2 queries */
721eaf0ac3Slogwang 	uint64_t igps_rcv_v3_queries;	/* received IGMPv3 queries */
731eaf0ac3Slogwang 	uint64_t igps_rcv_badqueries;	/* received invalid queries */
741eaf0ac3Slogwang 	uint64_t igps_rcv_gen_queries;	/* received general queries */
751eaf0ac3Slogwang 	uint64_t igps_rcv_group_queries;/* received group queries */
761eaf0ac3Slogwang 	uint64_t igps_rcv_gsr_queries;	/* received group-source queries */
771eaf0ac3Slogwang 	uint64_t igps_drop_gsr_queries;	/* dropped group-source queries */
781eaf0ac3Slogwang 	/*
791eaf0ac3Slogwang 	 * Report statistics.
801eaf0ac3Slogwang 	 */
811eaf0ac3Slogwang 	uint64_t igps_rcv_reports;	/* received membership reports */
821eaf0ac3Slogwang 	uint64_t igps_rcv_badreports;	/* received invalid reports */
831eaf0ac3Slogwang 	uint64_t igps_rcv_ourreports;	/* received reports for our groups */
841eaf0ac3Slogwang 	uint64_t igps_rcv_nora;		/* received w/o Router Alert option */
851eaf0ac3Slogwang 	uint64_t igps_snd_reports;	/* sent membership reports */
861eaf0ac3Slogwang 	/*
871eaf0ac3Slogwang 	 * Padding for future additions.
881eaf0ac3Slogwang 	 */
891eaf0ac3Slogwang 	uint64_t __igps_pad[4];
901eaf0ac3Slogwang };
911eaf0ac3Slogwang #define IGPS_VERSION_3	3		/* as of FreeBSD 8.x */
921eaf0ac3Slogwang #define IGPS_VERSION3_LEN		168
931eaf0ac3Slogwang #ifdef CTASSERT
941eaf0ac3Slogwang CTASSERT(sizeof(struct igmpstat) == IGPS_VERSION3_LEN);
951eaf0ac3Slogwang #endif
961eaf0ac3Slogwang 
971eaf0ac3Slogwang /*
981eaf0ac3Slogwang  * Identifiers for IGMP sysctl nodes
991eaf0ac3Slogwang  */
1001eaf0ac3Slogwang #define IGMPCTL_STATS		1	/* statistics (read-only) */
1011eaf0ac3Slogwang 
1021eaf0ac3Slogwang #define IGMP_RANDOM_DELAY(X) (random() % (X) + 1)
1031eaf0ac3Slogwang #define IGMP_MAX_STATE_CHANGES		24 /* Max pending changes per group */
1041eaf0ac3Slogwang 
1051eaf0ac3Slogwang /*
1061eaf0ac3Slogwang  * IGMP per-group states.
1071eaf0ac3Slogwang  */
1081eaf0ac3Slogwang #define IGMP_NOT_MEMBER			0 /* Can garbage collect in_multi */
1091eaf0ac3Slogwang #define IGMP_SILENT_MEMBER		1 /* Do not perform IGMP for group */
1101eaf0ac3Slogwang #define IGMP_REPORTING_MEMBER		2 /* IGMPv1/2/3 we are reporter */
1111eaf0ac3Slogwang #define IGMP_IDLE_MEMBER		3 /* IGMPv1/2 we reported last */
1121eaf0ac3Slogwang #define IGMP_LAZY_MEMBER		4 /* IGMPv1/2 other member reporting */
1131eaf0ac3Slogwang #define IGMP_SLEEPING_MEMBER		5 /* IGMPv1/2 start query response */
1141eaf0ac3Slogwang #define IGMP_AWAKENING_MEMBER		6 /* IGMPv1/2 group timer will start */
1151eaf0ac3Slogwang #define IGMP_G_QUERY_PENDING_MEMBER	7 /* IGMPv3 group query pending */
1161eaf0ac3Slogwang #define IGMP_SG_QUERY_PENDING_MEMBER	8 /* IGMPv3 source query pending */
1171eaf0ac3Slogwang #define IGMP_LEAVING_MEMBER		9 /* IGMPv3 dying gasp (pending last */
1181eaf0ac3Slogwang 					  /* retransmission of INCLUDE {}) */
1191eaf0ac3Slogwang 
1201eaf0ac3Slogwang /*
1211eaf0ac3Slogwang  * IGMP version tag.
1221eaf0ac3Slogwang  */
1231eaf0ac3Slogwang #define IGMP_VERSION_NONE		0 /* Invalid */
1241eaf0ac3Slogwang #define IGMP_VERSION_1			1
1251eaf0ac3Slogwang #define IGMP_VERSION_2			2
1261eaf0ac3Slogwang #define IGMP_VERSION_3			3 /* Default */
1271eaf0ac3Slogwang 
1281eaf0ac3Slogwang /*
1291eaf0ac3Slogwang  * IGMPv3 protocol control variables.
1301eaf0ac3Slogwang  */
1311eaf0ac3Slogwang #define IGMP_RV_INIT		2	/* Robustness Variable */
1321eaf0ac3Slogwang #define IGMP_RV_MIN		1
1331eaf0ac3Slogwang #define IGMP_RV_MAX		7
1341eaf0ac3Slogwang 
1351eaf0ac3Slogwang #define IGMP_QI_INIT		125	/* Query Interval (s) */
1361eaf0ac3Slogwang #define IGMP_QI_MIN		1
1371eaf0ac3Slogwang #define IGMP_QI_MAX		255
1381eaf0ac3Slogwang 
1391eaf0ac3Slogwang #define IGMP_QRI_INIT		10	/* Query Response Interval (s) */
1401eaf0ac3Slogwang #define IGMP_QRI_MIN		1
1411eaf0ac3Slogwang #define IGMP_QRI_MAX		255
1421eaf0ac3Slogwang 
1431eaf0ac3Slogwang #define IGMP_URI_INIT		3	/* Unsolicited Report Interval (s) */
1441eaf0ac3Slogwang #define IGMP_URI_MIN		0
1451eaf0ac3Slogwang #define IGMP_URI_MAX		10
1461eaf0ac3Slogwang 
1471eaf0ac3Slogwang #define IGMP_MAX_G_GS_PACKETS		8 /* # of packets to answer G/GS */
1481eaf0ac3Slogwang #define IGMP_MAX_STATE_CHANGE_PACKETS	8 /* # of packets per state change */
1491eaf0ac3Slogwang #define IGMP_MAX_RESPONSE_PACKETS	16 /* # of packets for general query */
1501eaf0ac3Slogwang #define IGMP_MAX_RESPONSE_BURST		4 /* # of responses to send at once */
1511eaf0ac3Slogwang #define IGMP_RESPONSE_BURST_INTERVAL	(PR_FASTHZ / 2)	/* 500ms */
1521eaf0ac3Slogwang 
1531eaf0ac3Slogwang /*
1541eaf0ac3Slogwang  * IGMP-specific mbuf flags.
1551eaf0ac3Slogwang  */
1561eaf0ac3Slogwang #define M_IGMPV2	M_PROTO1	/* Packet is IGMPv2 */
1571eaf0ac3Slogwang #define M_IGMPV3_HDR	M_PROTO2	/* Packet has IGMPv3 headers */
1581eaf0ac3Slogwang #define M_GROUPREC	M_PROTO3	/* mbuf chain is a group record */
1591eaf0ac3Slogwang #define M_IGMP_LOOP	M_PROTO4	/* transmit on loif, not real ifp */
1601eaf0ac3Slogwang 
1611eaf0ac3Slogwang /*
1621eaf0ac3Slogwang  * Default amount of leading space for IGMPv3 to allocate at the
1631eaf0ac3Slogwang  * beginning of its mbuf packet chains, to avoid fragmentation and
1641eaf0ac3Slogwang  * unnecessary allocation of leading mbufs.
1651eaf0ac3Slogwang  */
1661eaf0ac3Slogwang #define RAOPT_LEN	4		/* Length of IP Router Alert option */
1671eaf0ac3Slogwang #define	IGMP_LEADINGSPACE		\
1681eaf0ac3Slogwang 	(sizeof(struct ip) + RAOPT_LEN + sizeof(struct igmp_report))
1691eaf0ac3Slogwang 
1701eaf0ac3Slogwang /*
1711eaf0ac3Slogwang  * Structure returned by net.inet.igmp.ifinfo sysctl.
1721eaf0ac3Slogwang  */
1731eaf0ac3Slogwang struct igmp_ifinfo {
1741eaf0ac3Slogwang 	uint32_t igi_version;	/* IGMPv3 Host Compatibility Mode */
1751eaf0ac3Slogwang 	uint32_t igi_v1_timer;	/* IGMPv1 Querier Present timer (s) */
1761eaf0ac3Slogwang 	uint32_t igi_v2_timer;	/* IGMPv2 Querier Present timer (s) */
1771eaf0ac3Slogwang 	uint32_t igi_v3_timer;	/* IGMPv3 General Query (interface) timer (s)*/
1781eaf0ac3Slogwang 	uint32_t igi_flags;	/* IGMP per-interface flags */
1791eaf0ac3Slogwang #define IGIF_SILENT	0x00000001	/* Do not use IGMP on this ifp */
1801eaf0ac3Slogwang #define IGIF_LOOPBACK	0x00000002	/* Send IGMP reports to loopback */
1811eaf0ac3Slogwang 	uint32_t igi_rv;	/* IGMPv3 Robustness Variable */
1821eaf0ac3Slogwang 	uint32_t igi_qi;	/* IGMPv3 Query Interval (s) */
1831eaf0ac3Slogwang 	uint32_t igi_qri;	/* IGMPv3 Query Response Interval (s) */
1841eaf0ac3Slogwang 	uint32_t igi_uri;	/* IGMPv3 Unsolicited Report Interval (s) */
1851eaf0ac3Slogwang };
1861eaf0ac3Slogwang 
1871eaf0ac3Slogwang #ifdef _KERNEL
188*d4a07e70Sfengbojiang #include <sys/counter.h>
189*d4a07e70Sfengbojiang 
190*d4a07e70Sfengbojiang VNET_PCPUSTAT_DECLARE(struct igmpstat, igmpstat);
191*d4a07e70Sfengbojiang #define	IGMPSTAT_ADD(name, val)	\
192*d4a07e70Sfengbojiang     VNET_PCPUSTAT_ADD(struct igmpstat, igmpstat, name, (val))
1931eaf0ac3Slogwang #define	IGMPSTAT_INC(name)	IGMPSTAT_ADD(name, 1)
1941eaf0ac3Slogwang 
1951eaf0ac3Slogwang /*
1961eaf0ac3Slogwang  * Subsystem lock macros.
1971eaf0ac3Slogwang  * The IGMP lock is only taken with IGMP. Currently it is system-wide.
1981eaf0ac3Slogwang  * VIMAGE: The lock could be pushed to per-VIMAGE granularity in future.
1991eaf0ac3Slogwang  */
2001eaf0ac3Slogwang #define	IGMP_LOCK_INIT()	mtx_init(&igmp_mtx, "igmp_mtx", NULL, MTX_DEF)
2011eaf0ac3Slogwang #define	IGMP_LOCK_DESTROY()	mtx_destroy(&igmp_mtx)
2021eaf0ac3Slogwang #define	IGMP_LOCK()		mtx_lock(&igmp_mtx)
2031eaf0ac3Slogwang #define	IGMP_LOCK_ASSERT()	mtx_assert(&igmp_mtx, MA_OWNED)
2041eaf0ac3Slogwang #define	IGMP_UNLOCK()		mtx_unlock(&igmp_mtx)
2051eaf0ac3Slogwang #define	IGMP_UNLOCK_ASSERT()	mtx_assert(&igmp_mtx, MA_NOTOWNED)
2061eaf0ac3Slogwang 
2071eaf0ac3Slogwang /*
2081eaf0ac3Slogwang  * Per-interface IGMP router version information.
2091eaf0ac3Slogwang  */
2101eaf0ac3Slogwang struct igmp_ifsoftc {
2111eaf0ac3Slogwang 	LIST_ENTRY(igmp_ifsoftc) igi_link;
2121eaf0ac3Slogwang 	struct ifnet *igi_ifp;	/* pointer back to interface */
2131eaf0ac3Slogwang 	uint32_t igi_version;	/* IGMPv3 Host Compatibility Mode */
2141eaf0ac3Slogwang 	uint32_t igi_v1_timer;	/* IGMPv1 Querier Present timer (s) */
2151eaf0ac3Slogwang 	uint32_t igi_v2_timer;	/* IGMPv2 Querier Present timer (s) */
2161eaf0ac3Slogwang 	uint32_t igi_v3_timer;	/* IGMPv3 General Query (interface) timer (s)*/
2171eaf0ac3Slogwang 	uint32_t igi_flags;	/* IGMP per-interface flags */
2181eaf0ac3Slogwang 	uint32_t igi_rv;	/* IGMPv3 Robustness Variable */
2191eaf0ac3Slogwang 	uint32_t igi_qi;	/* IGMPv3 Query Interval (s) */
2201eaf0ac3Slogwang 	uint32_t igi_qri;	/* IGMPv3 Query Response Interval (s) */
2211eaf0ac3Slogwang 	uint32_t igi_uri;	/* IGMPv3 Unsolicited Report Interval (s) */
2221eaf0ac3Slogwang 	struct mbufq	igi_gq;		/* general query responses queue */
2231eaf0ac3Slogwang };
2241eaf0ac3Slogwang 
2251eaf0ac3Slogwang int	igmp_change_state(struct in_multi *);
2261eaf0ac3Slogwang void	igmp_fasttimo(void);
2271eaf0ac3Slogwang struct igmp_ifsoftc *
2281eaf0ac3Slogwang 	igmp_domifattach(struct ifnet *);
2291eaf0ac3Slogwang void	igmp_domifdetach(struct ifnet *);
2301eaf0ac3Slogwang void	igmp_ifdetach(struct ifnet *);
2311eaf0ac3Slogwang int	igmp_input(struct mbuf **, int *, int);
2321eaf0ac3Slogwang void	igmp_slowtimo(void);
2331eaf0ac3Slogwang 
2341eaf0ac3Slogwang SYSCTL_DECL(_net_inet_igmp);
2351eaf0ac3Slogwang 
2361eaf0ac3Slogwang #endif /* _KERNEL */
2371eaf0ac3Slogwang #endif
238