+#define M_IGMPV2 M_PROTO1 /* Packet is IGMPv2 */
+#define M_IGMPV3_HDR M_PROTO2 /* Packet has IGMPv3 headers */
+#define M_GROUPREC M_PROTO3 /* mbuf chain is a group record */
+#define M_IGMP_LOOP M_LOOP /* transmit on loif, not real ifp */
+
+/*
+ * Default amount of leading space for IGMPv3 to allocate at the
+ * beginning of its mbuf packet chains, to avoid fragmentation and
+ * unnecessary allocation of leading mbufs.
+ */
+#define RAOPT_LEN 4 /* Length of IP Router Alert option */
+#define IGMP_LEADINGSPACE \
+ (sizeof(struct ip) + RAOPT_LEN + sizeof(struct igmp_report))
+
+struct igmp_ifinfo {
+ decl_lck_mtx_data(, igi_lock);
+ uint32_t igi_refcnt; /* reference count */
+ uint32_t igi_debug; /* see ifa_debug flags */
+ LIST_ENTRY(igmp_ifinfo) igi_link;
+ struct ifnet *igi_ifp; /* interface this instance belongs to */
+ uint32_t igi_version; /* IGMPv3 Host Compatibility Mode */
+ uint32_t igi_v1_timer; /* IGMPv1 Querier Present timer (s) */
+ uint32_t igi_v2_timer; /* IGMPv2 Querier Present timer (s) */
+ uint32_t igi_v3_timer; /* IGMPv3 General Query (interface) timer (s)*/
+ uint32_t igi_flags; /* IGMP per-interface flags */
+ uint32_t igi_rv; /* IGMPv3 Robustness Variable */
+ uint32_t igi_qi; /* IGMPv3 Query Interval (s) */
+ uint32_t igi_qri; /* IGMPv3 Query Response Interval (s) */
+ uint32_t igi_uri; /* IGMPv3 Unsolicited Report Interval (s) */
+ SLIST_HEAD(,in_multi) igi_relinmhead; /* released groups */
+ struct ifqueue igi_gq; /* queue of general query responses */
+ struct ifqueue igi_v2q; /* queue of v1/v2 packets */
+};
+
+#define IGI_LOCK_ASSERT_HELD(_igi) \
+ lck_mtx_assert(&(_igi)->igi_lock, LCK_MTX_ASSERT_OWNED)
+
+#define IGI_LOCK_ASSERT_NOTHELD(_igi) \
+ lck_mtx_assert(&(_igi)->igi_lock, LCK_MTX_ASSERT_NOTOWNED)
+
+#define IGI_LOCK(_igi) \
+ lck_mtx_lock(&(_igi)->igi_lock)
+
+#define IGI_LOCK_SPIN(_igi) \
+ lck_mtx_lock_spin(&(_igi)->igi_lock)
+
+#define IGI_CONVERT_LOCK(_igi) do { \
+ IGI_LOCK_ASSERT_HELD(_igi); \
+ lck_mtx_convert_spin(&(_igi)->igi_lock); \
+} while (0)
+
+#define IGI_UNLOCK(_igi) \
+ lck_mtx_unlock(&(_igi)->igi_lock)
+
+#define IGI_ADDREF(_igi) \
+ igi_addref(_igi, 0)
+
+#define IGI_ADDREF_LOCKED(_igi) \
+ igi_addref(_igi, 1)
+
+#define IGI_REMREF(_igi) \
+ igi_remref(_igi)