xref: /openbmc/linux/include/linux/igmp.h (revision 33e972bd)
12874c5fdSThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-or-later */
21da177e4SLinus Torvalds /*
31da177e4SLinus Torvalds  *	Linux NET3:	Internet Group Management Protocol  [IGMP]
41da177e4SLinus Torvalds  *
51da177e4SLinus Torvalds  *	Authors:
6113aa838SAlan Cox  *		Alan Cox <alan@lxorguk.ukuu.org.uk>
71da177e4SLinus Torvalds  *
81da177e4SLinus Torvalds  *	Extended to talk the BSD extended IGMP protocol of mrouted 3.6
91da177e4SLinus Torvalds  */
101da177e4SLinus Torvalds #ifndef _LINUX_IGMP_H
111da177e4SLinus Torvalds #define _LINUX_IGMP_H
121da177e4SLinus Torvalds 
131da177e4SLinus Torvalds #include <linux/skbuff.h>
14d7fe0f24SAl Viro #include <linux/timer.h>
151da177e4SLinus Torvalds #include <linux/in.h>
16ba5ea614SLinus Lüssing #include <linux/ip.h>
178851ab52SReshetova, Elena #include <linux/refcount.h>
18ac62f606SJakub Kicinski #include <linux/sockptr.h>
19607ca46eSDavid Howells #include <uapi/linux/igmp.h>
201da177e4SLinus Torvalds 
igmp_hdr(const struct sk_buff * skb)21cc32e054SJoe Perches static inline struct igmphdr *igmp_hdr(const struct sk_buff *skb)
22cc32e054SJoe Perches {
23cc32e054SJoe Perches 	return (struct igmphdr *)skb_transport_header(skb);
24cc32e054SJoe Perches }
25cc32e054SJoe Perches 
26cc32e054SJoe Perches static inline struct igmpv3_report *
igmpv3_report_hdr(const struct sk_buff * skb)27cc32e054SJoe Perches 			igmpv3_report_hdr(const struct sk_buff *skb)
28cc32e054SJoe Perches {
29cc32e054SJoe Perches 	return (struct igmpv3_report *)skb_transport_header(skb);
30cc32e054SJoe Perches }
31cc32e054SJoe Perches 
32cc32e054SJoe Perches static inline struct igmpv3_query *
igmpv3_query_hdr(const struct sk_buff * skb)33cc32e054SJoe Perches 			igmpv3_query_hdr(const struct sk_buff *skb)
34cc32e054SJoe Perches {
35cc32e054SJoe Perches 	return (struct igmpv3_query *)skb_transport_header(skb);
36cc32e054SJoe Perches }
37cc32e054SJoe Perches 
38d94d9feeSEric Dumazet struct ip_sf_socklist {
391da177e4SLinus Torvalds 	unsigned int		sl_max;
401da177e4SLinus Torvalds 	unsigned int		sl_count;
41c85bb41eSFlavio Leitner 	struct rcu_head		rcu;
420ead3364SGustavo A. R. Silva 	__be32			sl_addr[];
431da177e4SLinus Torvalds };
441da177e4SLinus Torvalds 
451da177e4SLinus Torvalds #define IP_SFBLOCK	10	/* allocate this many at once */
461da177e4SLinus Torvalds 
471da177e4SLinus Torvalds /* ip_mc_socklist is real list now. Speed is not argument;
481da177e4SLinus Torvalds    this list never used in fast path code
491da177e4SLinus Torvalds  */
501da177e4SLinus Torvalds 
51d94d9feeSEric Dumazet struct ip_mc_socklist {
521d7138deSEric Dumazet 	struct ip_mc_socklist __rcu *next_rcu;
531da177e4SLinus Torvalds 	struct ip_mreqn		multi;
541da177e4SLinus Torvalds 	unsigned int		sfmode;		/* MCAST_{INCLUDE,EXCLUDE} */
551d7138deSEric Dumazet 	struct ip_sf_socklist __rcu	*sflist;
56c85bb41eSFlavio Leitner 	struct rcu_head		rcu;
571da177e4SLinus Torvalds };
581da177e4SLinus Torvalds 
59d94d9feeSEric Dumazet struct ip_sf_list {
601da177e4SLinus Torvalds 	struct ip_sf_list	*sf_next;
611da177e4SLinus Torvalds 	unsigned long		sf_count[2];	/* include/exclude counts */
620db355d4SEric Dumazet 	__be32			sf_inaddr;
631da177e4SLinus Torvalds 	unsigned char		sf_gsresp;	/* include in g & s response? */
641da177e4SLinus Torvalds 	unsigned char		sf_oldin;	/* change state */
651da177e4SLinus Torvalds 	unsigned char		sf_crcount;	/* retrans. left to send */
661da177e4SLinus Torvalds };
671da177e4SLinus Torvalds 
68d94d9feeSEric Dumazet struct ip_mc_list {
691da177e4SLinus Torvalds 	struct in_device	*interface;
70338fcf98SAlexey Dobriyan 	__be32			multiaddr;
711d7138deSEric Dumazet 	unsigned int		sfmode;
721da177e4SLinus Torvalds 	struct ip_sf_list	*sources;
731da177e4SLinus Torvalds 	struct ip_sf_list	*tomb;
741da177e4SLinus Torvalds 	unsigned long		sfcount[2];
751d7138deSEric Dumazet 	union {
761da177e4SLinus Torvalds 		struct ip_mc_list *next;
771d7138deSEric Dumazet 		struct ip_mc_list __rcu *next_rcu;
781d7138deSEric Dumazet 	};
79e9897071SEric Dumazet 	struct ip_mc_list __rcu *next_hash;
801da177e4SLinus Torvalds 	struct timer_list	timer;
811da177e4SLinus Torvalds 	int			users;
828851ab52SReshetova, Elena 	refcount_t		refcnt;
831da177e4SLinus Torvalds 	spinlock_t		lock;
841da177e4SLinus Torvalds 	char			tm_running;
851da177e4SLinus Torvalds 	char			reporter;
861da177e4SLinus Torvalds 	char			unsolicit_count;
871da177e4SLinus Torvalds 	char			loaded;
881da177e4SLinus Torvalds 	unsigned char		gsquery;	/* check source marks? */
891da177e4SLinus Torvalds 	unsigned char		crcount;
901d7138deSEric Dumazet 	struct rcu_head		rcu;
911da177e4SLinus Torvalds };
921da177e4SLinus Torvalds 
931da177e4SLinus Torvalds /* V3 exponential field decoding */
941da177e4SLinus Torvalds #define IGMPV3_MASK(value, nb) ((nb)>=32 ? (value) : ((1<<(nb))-1) & (value))
951da177e4SLinus Torvalds #define IGMPV3_EXP(thresh, nbmant, nbexp, value) \
961da177e4SLinus Torvalds 	((value) < (thresh) ? (value) : \
97fb47ddb2SDavid L Stevens         ((IGMPV3_MASK(value, nbmant) | (1<<(nbmant))) << \
981da177e4SLinus Torvalds          (IGMPV3_MASK((value) >> (nbmant), nbexp) + (nbexp))))
991da177e4SLinus Torvalds 
1001da177e4SLinus Torvalds #define IGMPV3_QQIC(value) IGMPV3_EXP(0x80, 4, 3, value)
1011da177e4SLinus Torvalds #define IGMPV3_MRC(value) IGMPV3_EXP(0x80, 4, 3, value)
1021da177e4SLinus Torvalds 
ip_mc_may_pull(struct sk_buff * skb,unsigned int len)103ba5ea614SLinus Lüssing static inline int ip_mc_may_pull(struct sk_buff *skb, unsigned int len)
104ba5ea614SLinus Lüssing {
105ba5ea614SLinus Lüssing 	if (skb_transport_offset(skb) + ip_transport_len(skb) < len)
106083b78a9SEric Dumazet 		return 0;
107ba5ea614SLinus Lüssing 
108ba5ea614SLinus Lüssing 	return pskb_may_pull(skb, len);
109ba5ea614SLinus Lüssing }
110ba5ea614SLinus Lüssing 
1112094acbbSAlexander Duyck extern int ip_check_mc_rcu(struct in_device *dev, __be32 mc_addr, __be32 src_addr, u8 proto);
1121da177e4SLinus Torvalds extern int igmp_rcv(struct sk_buff *);
1131da177e4SLinus Torvalds extern int ip_mc_join_group(struct sock *sk, struct ip_mreqn *imr);
1146e2059b5SHangbin Liu extern int ip_mc_join_group_ssm(struct sock *sk, struct ip_mreqn *imr,
1156e2059b5SHangbin Liu 				unsigned int mode);
1161da177e4SLinus Torvalds extern int ip_mc_leave_group(struct sock *sk, struct ip_mreqn *imr);
1171da177e4SLinus Torvalds extern void ip_mc_drop_socket(struct sock *sk);
1181da177e4SLinus Torvalds extern int ip_mc_source(int add, int omode, struct sock *sk,
1191da177e4SLinus Torvalds 		struct ip_mreq_source *mreqs, int ifindex);
1201da177e4SLinus Torvalds extern int ip_mc_msfilter(struct sock *sk, struct ip_msfilter *msf,int ifindex);
1211da177e4SLinus Torvalds extern int ip_mc_msfget(struct sock *sk, struct ip_msfilter *msf,
122728f064cSMartin KaFai Lau 			sockptr_t optval, sockptr_t optlen);
1231da177e4SLinus Torvalds extern int ip_mc_gsfget(struct sock *sk, struct group_filter *gsf,
124728f064cSMartin KaFai Lau 			sockptr_t optval, size_t offset);
125*33e972bdSEric Dumazet extern int ip_mc_sf_allow(const struct sock *sk, __be32 local, __be32 rmt,
12660d9b031SDavid Ahern 			  int dif, int sdif);
1271da177e4SLinus Torvalds extern void ip_mc_init_dev(struct in_device *);
1281da177e4SLinus Torvalds extern void ip_mc_destroy_dev(struct in_device *);
1291da177e4SLinus Torvalds extern void ip_mc_up(struct in_device *);
1301da177e4SLinus Torvalds extern void ip_mc_down(struct in_device *);
13175c78500SMoni Shoua extern void ip_mc_unmap(struct in_device *);
13275c78500SMoni Shoua extern void ip_mc_remap(struct in_device *);
1339fb20801SFlorian Fainelli 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)1349fb20801SFlorian Fainelli static inline void ip_mc_dec_group(struct in_device *in_dev, __be32 addr)
1359fb20801SFlorian Fainelli {
1369fb20801SFlorian Fainelli 	return __ip_mc_dec_group(in_dev, addr, GFP_KERNEL);
1379fb20801SFlorian Fainelli }
1389fb20801SFlorian Fainelli extern void __ip_mc_inc_group(struct in_device *in_dev, __be32 addr,
1399fb20801SFlorian Fainelli 			      gfp_t gfp);
1408f935bbdSAl Viro extern void ip_mc_inc_group(struct in_device *in_dev, __be32 addr);
141ba5ea614SLinus Lüssing int ip_mc_check_igmp(struct sk_buff *skb);
142a816c7c7SJay Vosburgh 
1431da177e4SLinus Torvalds #endif
144