xref: /linux/include/linux/igmp.h (revision 546b928da0427b0d6c663cbb992bd7bfa9ac7971)
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 /*
3  *	Linux NET3:	Internet Group Management Protocol  [IGMP]
4  *
5  *	Authors:
6  *		Alan Cox <alan@lxorguk.ukuu.org.uk>
7  *
8  *	Extended to talk the BSD extended IGMP protocol of mrouted 3.6
9  */
10 #ifndef _LINUX_IGMP_H
11 #define _LINUX_IGMP_H
12 
13 #include <linux/skbuff.h>
14 #include <linux/timer.h>
15 #include <linux/in.h>
16 #include <linux/ip.h>
17 #include <linux/refcount.h>
18 #include <linux/sockptr.h>
19 #include <uapi/linux/igmp.h>
20 
igmp_hdr(const struct sk_buff * skb)21 static inline struct igmphdr *igmp_hdr(const struct sk_buff *skb)
22 {
23 	return (struct igmphdr *)skb_transport_header(skb);
24 }
25 
26 static inline struct igmpv3_report *
igmpv3_report_hdr(const struct sk_buff * skb)27 			igmpv3_report_hdr(const struct sk_buff *skb)
28 {
29 	return (struct igmpv3_report *)skb_transport_header(skb);
30 }
31 
32 static inline struct igmpv3_query *
igmpv3_query_hdr(const struct sk_buff * skb)33 			igmpv3_query_hdr(const struct sk_buff *skb)
34 {
35 	return (struct igmpv3_query *)skb_transport_header(skb);
36 }
37 
38 struct ip_sf_socklist {
39 	unsigned int		sl_max;
40 	unsigned int		sl_count;
41 	struct rcu_head		rcu;
42 	__be32			sl_addr[] __counted_by(sl_max);
43 };
44 
45 #define IP_SFBLOCK	10	/* allocate this many at once */
46 
47 /* ip_mc_socklist is real list now. Speed is not argument;
48    this list never used in fast path code
49  */
50 
51 struct ip_mc_socklist {
52 	struct ip_mc_socklist __rcu *next_rcu;
53 	struct ip_mreqn		multi;
54 	unsigned int		sfmode;		/* MCAST_{INCLUDE,EXCLUDE} */
55 	struct ip_sf_socklist __rcu	*sflist;
56 	struct rcu_head		rcu;
57 };
58 
59 struct ip_sf_list {
60 	struct ip_sf_list __rcu	*sf_next;
61 	unsigned long		sf_count[2];	/* include/exclude counts */
62 	__be32			sf_inaddr;
63 	unsigned char		sf_gsresp;	/* include in g & s response? */
64 	unsigned char		sf_oldin;	/* change state */
65 	unsigned char		sf_crcount;	/* retrans. left to send */
66 	struct rcu_head		rcu;
67 };
68 
69 struct ip_mc_list {
70 	struct in_device	*interface;
71 	__be32			multiaddr;
72 	unsigned int		sfmode;
73 	struct ip_sf_list __rcu	*sources;
74 	struct ip_sf_list __rcu	*tomb;
75 	unsigned long		sfcount[2];
76 	union {
77 		struct ip_mc_list *next;
78 		struct ip_mc_list __rcu *next_rcu;
79 	};
80 	struct ip_mc_list __rcu *next_hash;
81 	struct timer_list	timer;
82 	int			users;
83 	refcount_t		refcnt;
84 	spinlock_t		lock;
85 	char			tm_running;
86 	char			reporter;
87 	char			unsolicit_count;
88 	char			loaded;
89 	unsigned char		gsquery;	/* check source marks? */
90 	unsigned char		crcount;
91 	unsigned long		mca_cstamp;
92 	unsigned long		mca_tstamp;
93 	struct rcu_head		rcu;
94 };
95 
96 /* RFC3376, relevant sections:
97  *  - 4.1.1. Maximum Response Code
98  *  - 4.1.7. QQIC (Querier's Query Interval Code)
99  *
100  * For both MRC and QQIC, values >= 128 use the same floating-point
101  * encoding as follows:
102  *
103  *  0 1 2 3 4 5 6 7
104  * +-+-+-+-+-+-+-+-+
105  * |1| exp | mant  |
106  * +-+-+-+-+-+-+-+-+
107  */
108 #define IGMPV3_FP_EXP(value)		(((value) >> 4) & 0x07)
109 #define IGMPV3_FP_MAN(value)		((value) & 0x0f)
110 
111 /* IGMPv3 floating-point exponential field min threshold */
112 #define IGMPV3_EXP_MIN_THRESHOLD	128
113 /* IGMPv3 FP max threshold (mant = 0xF, exp = 7) -> 31744 */
114 #define IGMPV3_EXP_MAX_THRESHOLD	31744
115 
116 /* V3 exponential field encoding */
117 
118 /* IGMPv3 MRC/QQIC 8-bit exponential field encode
119  *
120  * RFC3376, 4.1.1 & 4.1.7. defines only the decoding formula:
121  *     MRT/QQI = (mant | 0x10) << (exp + 3)
122  *
123  * but does NOT define the encoding procedure. To derive exponent:
124  *
125  * For any value of mantissa and exponent, the decoding formula
126  * indicates that the "hidden bit" (0x10) is shifted 4 bits left
127  * to sit above the 4-bit mantissa. The RFC again shifts this
128  * entire block left by (exp + 3) to reconstruct the value.
129  * So, 'hidden bit' is the MSB which is shifted by (4 + exp + 3).
130  *
131  * Total left shift of the 'hidden bit' = 4 + (exp + 3) = exp + 7.
132  * This is the MSB at the 0-based bit position: (exp + 7).
133  * Since fls() is 1-based, fls(value) - 1 = exp + 7.
134  *
135  * Therefore:
136  *     exp  = fls(value) - 8
137  *     mant = (value >> (exp + 3)) & 0x0F
138  *
139  * Final encoding formula:
140  *     0x80 | (exp << 4) | mant
141  *
142  * Example (value = 3200):
143  *  0               1
144  *  0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
145  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
146  * |0 0 0 0 1 1 0 0 1 0 0 0 0 0 0 0| (value = 3200)
147  * |        ^-^-mant^ ^..(exp+3)..^| exp = 4, mant = 9
148  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
149  *
150  * Encoded:
151  *   0x80 | (4 << 4) | 9 = 0xC9
152  */
igmpv3_exp_field_encode(unsigned long value)153 static inline u8 igmpv3_exp_field_encode(unsigned long value)
154 {
155 	u8 mc_exp, mc_man;
156 
157 	/* MRC/QQIC < 128 is literal */
158 	if (value < IGMPV3_EXP_MIN_THRESHOLD)
159 		return value;
160 
161 	/* Saturate at max representable (mant = 0xF, exp = 7) -> 31744 */
162 	if (value >= IGMPV3_EXP_MAX_THRESHOLD)
163 		return 0xFF;
164 
165 	mc_exp  = fls(value) - 8;
166 	mc_man = (value >> (mc_exp + 3)) & 0x0F;
167 
168 	return 0x80 | (mc_exp << 4) | mc_man;
169 }
170 
171 /* Calculate Maximum Response Code from Max Resp Time
172  *
173  * RFC3376, relevant sections:
174  *  - 4.1.1. Maximum Response Code
175  *  - 8.3. Query Response Interval
176  *
177  * MRC represents the encoded form of Max Resp Time (MRT); once
178  * decoded, the resulting value is in units of 0.1 seconds (100 ms).
179  */
igmpv3_mrc(unsigned long mrt)180 static inline u8 igmpv3_mrc(unsigned long mrt)
181 {
182 	return igmpv3_exp_field_encode(mrt);
183 }
184 
185 /* Calculate Querier's Query Interval Code from Querier's Query Interval
186  *
187  * RFC3376, relevant sections:
188  *  - 4.1.7. QQIC (Querier's Query Interval Code)
189  *  - 8.2. Query Interval
190  *  - 8.12. Older Version Querier Present Timeout
191  *    (the [Query Interval] in the last Query received)
192  *
193  * QQIC represents the encoded form of Querier's Query Interval (QQI);
194  * once decoded, the resulting value is in units of seconds.
195  */
igmpv3_qqic(unsigned long qi)196 static inline u8 igmpv3_qqic(unsigned long qi)
197 {
198 	return igmpv3_exp_field_encode(qi);
199 }
200 
201 /* V3 exponential field decoding */
202 
203 /* IGMPv3 MRC/QQIC 8-bit exponential field decode
204  *
205  * RFC3376, 4.1.1 & 4.1.7. defines the decoding formula:
206  *      0 1 2 3 4 5 6 7
207  *     +-+-+-+-+-+-+-+-+
208  *     |1| exp | mant  |
209  *     +-+-+-+-+-+-+-+-+
210  * Max Resp Time = (mant | 0x10) << (exp + 3)
211  * QQI = (mant | 0x10) << (exp + 3)
212  */
igmpv3_exp_field_decode(const u8 code)213 static inline unsigned long igmpv3_exp_field_decode(const u8 code)
214 {
215 	if (code < IGMPV3_EXP_MIN_THRESHOLD) {
216 		return code;
217 	} else {
218 		unsigned long mc_man, mc_exp;
219 
220 		mc_exp = IGMPV3_FP_EXP(code);
221 		mc_man = IGMPV3_FP_MAN(code);
222 
223 		return (mc_man | 0x10) << (mc_exp + 3);
224 	}
225 }
226 
227 /* Calculate Max Resp Time from Maximum Response Code
228  *
229  * RFC3376, relevant sections:
230  *  - 4.1.1. Maximum Response Code
231  *  - 8.3. Query Response Interval
232  *
233  * After decode, MRC represents the Maximum Response Time (MRT) in
234  * units of 0.1 seconds (100 ms).
235  */
igmpv3_mrt(const struct igmpv3_query * ih3)236 static inline unsigned long igmpv3_mrt(const struct igmpv3_query *ih3)
237 {
238 	return igmpv3_exp_field_decode(ih3->code);
239 }
240 
241 /* Calculate Querier's Query Interval from Querier's Query Interval Code
242  *
243  * RFC3376, relevant sections:
244  *  - 4.1.7. QQIC (Querier's Query Interval Code)
245  *  - 8.2. Query Interval
246  *  - 8.12. Older Version Querier Present Timeout
247  *    (the [Query Interval] in the last Query received)
248  *
249  * After decode, QQIC represents the Querier's Query Interval in units
250  * of seconds.
251  */
igmpv3_qqi(const struct igmpv3_query * ih3)252 static inline unsigned long igmpv3_qqi(const struct igmpv3_query *ih3)
253 {
254 	return igmpv3_exp_field_decode(ih3->qqic);
255 }
256 
ip_mc_may_pull(struct sk_buff * skb,unsigned int len)257 static inline int ip_mc_may_pull(struct sk_buff *skb, unsigned int len)
258 {
259 	if (skb_transport_offset(skb) + ip_transport_len(skb) < len)
260 		return 0;
261 
262 	return pskb_may_pull(skb, len);
263 }
264 
265 extern int ip_check_mc_rcu(struct in_device *dev, __be32 mc_addr, __be32 src_addr, u8 proto);
266 extern int igmp_rcv(struct sk_buff *);
267 extern int ip_mc_join_group(struct sock *sk, struct ip_mreqn *imr);
268 extern int ip_mc_join_group_ssm(struct sock *sk, struct ip_mreqn *imr,
269 				unsigned int mode);
270 extern int ip_mc_leave_group(struct sock *sk, struct ip_mreqn *imr);
271 extern void ip_mc_drop_socket(struct sock *sk);
272 extern int ip_mc_source(int add, int omode, struct sock *sk,
273 		struct ip_mreq_source *mreqs, int ifindex);
274 extern int ip_mc_msfilter(struct sock *sk, struct ip_msfilter *msf,int ifindex);
275 extern int ip_mc_msfget(struct sock *sk, struct ip_msfilter *msf,
276 			sockptr_t optval, sockptr_t optlen);
277 extern int ip_mc_gsfget(struct sock *sk, struct group_filter *gsf,
278 			sockptr_t optval, size_t offset);
279 extern int ip_mc_sf_allow(const struct sock *sk, __be32 local, __be32 rmt,
280 			  int dif, int sdif);
281 extern void ip_mc_init_dev(struct in_device *);
282 extern void ip_mc_destroy_dev(struct in_device *);
283 extern void ip_mc_up(struct in_device *);
284 extern void ip_mc_down(struct in_device *);
285 extern void ip_mc_unmap(struct in_device *);
286 extern void ip_mc_remap(struct in_device *);
287 extern void __ip_mc_dec_group(struct in_device *in_dev, __be32 addr, gfp_t gfp);
ip_mc_dec_group(struct in_device * in_dev,__be32 addr)288 static inline void ip_mc_dec_group(struct in_device *in_dev, __be32 addr)
289 {
290 	return __ip_mc_dec_group(in_dev, addr, GFP_KERNEL);
291 }
292 extern void __ip_mc_inc_group(struct in_device *in_dev, __be32 addr,
293 			      gfp_t gfp);
294 extern void ip_mc_inc_group(struct in_device *in_dev, __be32 addr);
295 int ip_mc_check_igmp(struct sk_buff *skb);
296 
297 #endif
298