xref: /openbmc/linux/net/bridge/br_multicast.c (revision eb1d16414339a6e113d89e2cca2556005d7ce919)
1*eb1d1641SHerbert Xu /*
2*eb1d1641SHerbert Xu  * Bridge multicast support.
3*eb1d1641SHerbert Xu  *
4*eb1d1641SHerbert Xu  * Copyright (c) 2010 Herbert Xu <herbert@gondor.apana.org.au>
5*eb1d1641SHerbert Xu  *
6*eb1d1641SHerbert Xu  * This program is free software; you can redistribute it and/or modify it
7*eb1d1641SHerbert Xu  * under the terms of the GNU General Public License as published by the Free
8*eb1d1641SHerbert Xu  * Software Foundation; either version 2 of the License, or (at your option)
9*eb1d1641SHerbert Xu  * any later version.
10*eb1d1641SHerbert Xu  *
11*eb1d1641SHerbert Xu  */
12*eb1d1641SHerbert Xu 
13*eb1d1641SHerbert Xu #include <linux/err.h>
14*eb1d1641SHerbert Xu #include <linux/if_ether.h>
15*eb1d1641SHerbert Xu #include <linux/igmp.h>
16*eb1d1641SHerbert Xu #include <linux/jhash.h>
17*eb1d1641SHerbert Xu #include <linux/kernel.h>
18*eb1d1641SHerbert Xu #include <linux/netdevice.h>
19*eb1d1641SHerbert Xu #include <linux/netfilter_bridge.h>
20*eb1d1641SHerbert Xu #include <linux/random.h>
21*eb1d1641SHerbert Xu #include <linux/rculist.h>
22*eb1d1641SHerbert Xu #include <linux/skbuff.h>
23*eb1d1641SHerbert Xu #include <linux/slab.h>
24*eb1d1641SHerbert Xu #include <linux/timer.h>
25*eb1d1641SHerbert Xu #include <net/ip.h>
26*eb1d1641SHerbert Xu 
27*eb1d1641SHerbert Xu #include "br_private.h"
28*eb1d1641SHerbert Xu 
29*eb1d1641SHerbert Xu static inline int br_ip_hash(struct net_bridge_mdb_htable *mdb, __be32 ip)
30*eb1d1641SHerbert Xu {
31*eb1d1641SHerbert Xu 	return jhash_1word(mdb->secret, (u32)ip) & (mdb->max - 1);
32*eb1d1641SHerbert Xu }
33*eb1d1641SHerbert Xu 
34*eb1d1641SHerbert Xu static struct net_bridge_mdb_entry *__br_mdb_ip_get(
35*eb1d1641SHerbert Xu 	struct net_bridge_mdb_htable *mdb, __be32 dst, int hash)
36*eb1d1641SHerbert Xu {
37*eb1d1641SHerbert Xu 	struct net_bridge_mdb_entry *mp;
38*eb1d1641SHerbert Xu 	struct hlist_node *p;
39*eb1d1641SHerbert Xu 
40*eb1d1641SHerbert Xu 	hlist_for_each_entry(mp, p, &mdb->mhash[hash], hlist[mdb->ver]) {
41*eb1d1641SHerbert Xu 		if (dst == mp->addr)
42*eb1d1641SHerbert Xu 			return mp;
43*eb1d1641SHerbert Xu 	}
44*eb1d1641SHerbert Xu 
45*eb1d1641SHerbert Xu 	return NULL;
46*eb1d1641SHerbert Xu }
47*eb1d1641SHerbert Xu 
48*eb1d1641SHerbert Xu static struct net_bridge_mdb_entry *br_mdb_ip_get(
49*eb1d1641SHerbert Xu 	struct net_bridge_mdb_htable *mdb, __be32 dst)
50*eb1d1641SHerbert Xu {
51*eb1d1641SHerbert Xu 	return __br_mdb_ip_get(mdb, dst, br_ip_hash(mdb, dst));
52*eb1d1641SHerbert Xu }
53*eb1d1641SHerbert Xu 
54*eb1d1641SHerbert Xu struct net_bridge_mdb_entry *br_mdb_get(struct net_bridge *br,
55*eb1d1641SHerbert Xu 					struct sk_buff *skb)
56*eb1d1641SHerbert Xu {
57*eb1d1641SHerbert Xu 	struct net_bridge_mdb_htable *mdb = br->mdb;
58*eb1d1641SHerbert Xu 
59*eb1d1641SHerbert Xu 	if (!mdb || br->multicast_disabled)
60*eb1d1641SHerbert Xu 		return NULL;
61*eb1d1641SHerbert Xu 
62*eb1d1641SHerbert Xu 	switch (skb->protocol) {
63*eb1d1641SHerbert Xu 	case htons(ETH_P_IP):
64*eb1d1641SHerbert Xu 		if (BR_INPUT_SKB_CB(skb)->igmp)
65*eb1d1641SHerbert Xu 			break;
66*eb1d1641SHerbert Xu 		return br_mdb_ip_get(mdb, ip_hdr(skb)->daddr);
67*eb1d1641SHerbert Xu 	}
68*eb1d1641SHerbert Xu 
69*eb1d1641SHerbert Xu 	return NULL;
70*eb1d1641SHerbert Xu }
71*eb1d1641SHerbert Xu 
72*eb1d1641SHerbert Xu static void br_mdb_free(struct rcu_head *head)
73*eb1d1641SHerbert Xu {
74*eb1d1641SHerbert Xu 	struct net_bridge_mdb_htable *mdb =
75*eb1d1641SHerbert Xu 		container_of(head, struct net_bridge_mdb_htable, rcu);
76*eb1d1641SHerbert Xu 	struct net_bridge_mdb_htable *old = mdb->old;
77*eb1d1641SHerbert Xu 
78*eb1d1641SHerbert Xu 	mdb->old = NULL;
79*eb1d1641SHerbert Xu 	kfree(old->mhash);
80*eb1d1641SHerbert Xu 	kfree(old);
81*eb1d1641SHerbert Xu }
82*eb1d1641SHerbert Xu 
83*eb1d1641SHerbert Xu static int br_mdb_copy(struct net_bridge_mdb_htable *new,
84*eb1d1641SHerbert Xu 		       struct net_bridge_mdb_htable *old,
85*eb1d1641SHerbert Xu 		       int elasticity)
86*eb1d1641SHerbert Xu {
87*eb1d1641SHerbert Xu 	struct net_bridge_mdb_entry *mp;
88*eb1d1641SHerbert Xu 	struct hlist_node *p;
89*eb1d1641SHerbert Xu 	int maxlen;
90*eb1d1641SHerbert Xu 	int len;
91*eb1d1641SHerbert Xu 	int i;
92*eb1d1641SHerbert Xu 
93*eb1d1641SHerbert Xu 	for (i = 0; i < old->max; i++)
94*eb1d1641SHerbert Xu 		hlist_for_each_entry(mp, p, &old->mhash[i], hlist[old->ver])
95*eb1d1641SHerbert Xu 			hlist_add_head(&mp->hlist[new->ver],
96*eb1d1641SHerbert Xu 				       &new->mhash[br_ip_hash(new, mp->addr)]);
97*eb1d1641SHerbert Xu 
98*eb1d1641SHerbert Xu 	if (!elasticity)
99*eb1d1641SHerbert Xu 		return 0;
100*eb1d1641SHerbert Xu 
101*eb1d1641SHerbert Xu 	maxlen = 0;
102*eb1d1641SHerbert Xu 	for (i = 0; i < new->max; i++) {
103*eb1d1641SHerbert Xu 		len = 0;
104*eb1d1641SHerbert Xu 		hlist_for_each_entry(mp, p, &new->mhash[i], hlist[new->ver])
105*eb1d1641SHerbert Xu 			len++;
106*eb1d1641SHerbert Xu 		if (len > maxlen)
107*eb1d1641SHerbert Xu 			maxlen = len;
108*eb1d1641SHerbert Xu 	}
109*eb1d1641SHerbert Xu 
110*eb1d1641SHerbert Xu 	return maxlen > elasticity ? -EINVAL : 0;
111*eb1d1641SHerbert Xu }
112*eb1d1641SHerbert Xu 
113*eb1d1641SHerbert Xu static void br_multicast_free_pg(struct rcu_head *head)
114*eb1d1641SHerbert Xu {
115*eb1d1641SHerbert Xu 	struct net_bridge_port_group *p =
116*eb1d1641SHerbert Xu 		container_of(head, struct net_bridge_port_group, rcu);
117*eb1d1641SHerbert Xu 
118*eb1d1641SHerbert Xu 	kfree(p);
119*eb1d1641SHerbert Xu }
120*eb1d1641SHerbert Xu 
121*eb1d1641SHerbert Xu static void br_multicast_free_group(struct rcu_head *head)
122*eb1d1641SHerbert Xu {
123*eb1d1641SHerbert Xu 	struct net_bridge_mdb_entry *mp =
124*eb1d1641SHerbert Xu 		container_of(head, struct net_bridge_mdb_entry, rcu);
125*eb1d1641SHerbert Xu 
126*eb1d1641SHerbert Xu 	kfree(mp);
127*eb1d1641SHerbert Xu }
128*eb1d1641SHerbert Xu 
129*eb1d1641SHerbert Xu static void br_multicast_group_expired(unsigned long data)
130*eb1d1641SHerbert Xu {
131*eb1d1641SHerbert Xu 	struct net_bridge_mdb_entry *mp = (void *)data;
132*eb1d1641SHerbert Xu 	struct net_bridge *br = mp->br;
133*eb1d1641SHerbert Xu 	struct net_bridge_mdb_htable *mdb;
134*eb1d1641SHerbert Xu 
135*eb1d1641SHerbert Xu 	spin_lock(&br->multicast_lock);
136*eb1d1641SHerbert Xu 	if (!netif_running(br->dev) || timer_pending(&mp->timer))
137*eb1d1641SHerbert Xu 		goto out;
138*eb1d1641SHerbert Xu 
139*eb1d1641SHerbert Xu 	if (!hlist_unhashed(&mp->mglist))
140*eb1d1641SHerbert Xu 		hlist_del_init(&mp->mglist);
141*eb1d1641SHerbert Xu 
142*eb1d1641SHerbert Xu 	if (mp->ports)
143*eb1d1641SHerbert Xu 		goto out;
144*eb1d1641SHerbert Xu 
145*eb1d1641SHerbert Xu 	mdb = br->mdb;
146*eb1d1641SHerbert Xu 	hlist_del_rcu(&mp->hlist[mdb->ver]);
147*eb1d1641SHerbert Xu 	mdb->size--;
148*eb1d1641SHerbert Xu 
149*eb1d1641SHerbert Xu 	del_timer(&mp->query_timer);
150*eb1d1641SHerbert Xu 	call_rcu_bh(&mp->rcu, br_multicast_free_group);
151*eb1d1641SHerbert Xu 
152*eb1d1641SHerbert Xu out:
153*eb1d1641SHerbert Xu 	spin_unlock(&br->multicast_lock);
154*eb1d1641SHerbert Xu }
155*eb1d1641SHerbert Xu 
156*eb1d1641SHerbert Xu static void br_multicast_del_pg(struct net_bridge *br,
157*eb1d1641SHerbert Xu 				struct net_bridge_port_group *pg)
158*eb1d1641SHerbert Xu {
159*eb1d1641SHerbert Xu 	struct net_bridge_mdb_htable *mdb = br->mdb;
160*eb1d1641SHerbert Xu 	struct net_bridge_mdb_entry *mp;
161*eb1d1641SHerbert Xu 	struct net_bridge_port_group *p;
162*eb1d1641SHerbert Xu 	struct net_bridge_port_group **pp;
163*eb1d1641SHerbert Xu 
164*eb1d1641SHerbert Xu 	mp = br_mdb_ip_get(mdb, pg->addr);
165*eb1d1641SHerbert Xu 	if (WARN_ON(!mp))
166*eb1d1641SHerbert Xu 		return;
167*eb1d1641SHerbert Xu 
168*eb1d1641SHerbert Xu 	for (pp = &mp->ports; (p = *pp); pp = &p->next) {
169*eb1d1641SHerbert Xu 		if (p != pg)
170*eb1d1641SHerbert Xu 			continue;
171*eb1d1641SHerbert Xu 
172*eb1d1641SHerbert Xu 		*pp = p->next;
173*eb1d1641SHerbert Xu 		hlist_del_init(&p->mglist);
174*eb1d1641SHerbert Xu 		del_timer(&p->timer);
175*eb1d1641SHerbert Xu 		del_timer(&p->query_timer);
176*eb1d1641SHerbert Xu 		call_rcu_bh(&p->rcu, br_multicast_free_pg);
177*eb1d1641SHerbert Xu 
178*eb1d1641SHerbert Xu 		if (!mp->ports && hlist_unhashed(&mp->mglist) &&
179*eb1d1641SHerbert Xu 		    netif_running(br->dev))
180*eb1d1641SHerbert Xu 			mod_timer(&mp->timer, jiffies);
181*eb1d1641SHerbert Xu 
182*eb1d1641SHerbert Xu 		return;
183*eb1d1641SHerbert Xu 	}
184*eb1d1641SHerbert Xu 
185*eb1d1641SHerbert Xu 	WARN_ON(1);
186*eb1d1641SHerbert Xu }
187*eb1d1641SHerbert Xu 
188*eb1d1641SHerbert Xu static void br_multicast_port_group_expired(unsigned long data)
189*eb1d1641SHerbert Xu {
190*eb1d1641SHerbert Xu 	struct net_bridge_port_group *pg = (void *)data;
191*eb1d1641SHerbert Xu 	struct net_bridge *br = pg->port->br;
192*eb1d1641SHerbert Xu 
193*eb1d1641SHerbert Xu 	spin_lock(&br->multicast_lock);
194*eb1d1641SHerbert Xu 	if (!netif_running(br->dev) || timer_pending(&pg->timer) ||
195*eb1d1641SHerbert Xu 	    hlist_unhashed(&pg->mglist))
196*eb1d1641SHerbert Xu 		goto out;
197*eb1d1641SHerbert Xu 
198*eb1d1641SHerbert Xu 	br_multicast_del_pg(br, pg);
199*eb1d1641SHerbert Xu 
200*eb1d1641SHerbert Xu out:
201*eb1d1641SHerbert Xu 	spin_unlock(&br->multicast_lock);
202*eb1d1641SHerbert Xu }
203*eb1d1641SHerbert Xu 
204*eb1d1641SHerbert Xu static int br_mdb_rehash(struct net_bridge_mdb_htable **mdbp, int max,
205*eb1d1641SHerbert Xu 			 int elasticity)
206*eb1d1641SHerbert Xu {
207*eb1d1641SHerbert Xu 	struct net_bridge_mdb_htable *old = *mdbp;
208*eb1d1641SHerbert Xu 	struct net_bridge_mdb_htable *mdb;
209*eb1d1641SHerbert Xu 	int err;
210*eb1d1641SHerbert Xu 
211*eb1d1641SHerbert Xu 	mdb = kmalloc(sizeof(*mdb), GFP_ATOMIC);
212*eb1d1641SHerbert Xu 	if (!mdb)
213*eb1d1641SHerbert Xu 		return -ENOMEM;
214*eb1d1641SHerbert Xu 
215*eb1d1641SHerbert Xu 	mdb->max = max;
216*eb1d1641SHerbert Xu 	mdb->old = old;
217*eb1d1641SHerbert Xu 
218*eb1d1641SHerbert Xu 	mdb->mhash = kzalloc(max * sizeof(*mdb->mhash), GFP_ATOMIC);
219*eb1d1641SHerbert Xu 	if (!mdb->mhash) {
220*eb1d1641SHerbert Xu 		kfree(mdb);
221*eb1d1641SHerbert Xu 		return -ENOMEM;
222*eb1d1641SHerbert Xu 	}
223*eb1d1641SHerbert Xu 
224*eb1d1641SHerbert Xu 	mdb->size = old ? old->size : 0;
225*eb1d1641SHerbert Xu 	mdb->ver = old ? old->ver ^ 1 : 0;
226*eb1d1641SHerbert Xu 
227*eb1d1641SHerbert Xu 	if (!old || elasticity)
228*eb1d1641SHerbert Xu 		get_random_bytes(&mdb->secret, sizeof(mdb->secret));
229*eb1d1641SHerbert Xu 	else
230*eb1d1641SHerbert Xu 		mdb->secret = old->secret;
231*eb1d1641SHerbert Xu 
232*eb1d1641SHerbert Xu 	if (!old)
233*eb1d1641SHerbert Xu 		goto out;
234*eb1d1641SHerbert Xu 
235*eb1d1641SHerbert Xu 	err = br_mdb_copy(mdb, old, elasticity);
236*eb1d1641SHerbert Xu 	if (err) {
237*eb1d1641SHerbert Xu 		kfree(mdb->mhash);
238*eb1d1641SHerbert Xu 		kfree(mdb);
239*eb1d1641SHerbert Xu 		return err;
240*eb1d1641SHerbert Xu 	}
241*eb1d1641SHerbert Xu 
242*eb1d1641SHerbert Xu 	call_rcu_bh(&mdb->rcu, br_mdb_free);
243*eb1d1641SHerbert Xu 
244*eb1d1641SHerbert Xu out:
245*eb1d1641SHerbert Xu 	rcu_assign_pointer(*mdbp, mdb);
246*eb1d1641SHerbert Xu 
247*eb1d1641SHerbert Xu 	return 0;
248*eb1d1641SHerbert Xu }
249*eb1d1641SHerbert Xu 
250*eb1d1641SHerbert Xu static struct sk_buff *br_multicast_alloc_query(struct net_bridge *br,
251*eb1d1641SHerbert Xu 						__be32 group)
252*eb1d1641SHerbert Xu {
253*eb1d1641SHerbert Xu 	struct sk_buff *skb;
254*eb1d1641SHerbert Xu 	struct igmphdr *ih;
255*eb1d1641SHerbert Xu 	struct ethhdr *eth;
256*eb1d1641SHerbert Xu 	struct iphdr *iph;
257*eb1d1641SHerbert Xu 
258*eb1d1641SHerbert Xu 	skb = netdev_alloc_skb_ip_align(br->dev, sizeof(*eth) + sizeof(*iph) +
259*eb1d1641SHerbert Xu 						 sizeof(*ih) + 4);
260*eb1d1641SHerbert Xu 	if (!skb)
261*eb1d1641SHerbert Xu 		goto out;
262*eb1d1641SHerbert Xu 
263*eb1d1641SHerbert Xu 	skb->protocol = htons(ETH_P_IP);
264*eb1d1641SHerbert Xu 
265*eb1d1641SHerbert Xu 	skb_reset_mac_header(skb);
266*eb1d1641SHerbert Xu 	eth = eth_hdr(skb);
267*eb1d1641SHerbert Xu 
268*eb1d1641SHerbert Xu 	memcpy(eth->h_source, br->dev->dev_addr, 6);
269*eb1d1641SHerbert Xu 	eth->h_dest[0] = 1;
270*eb1d1641SHerbert Xu 	eth->h_dest[1] = 0;
271*eb1d1641SHerbert Xu 	eth->h_dest[2] = 0x5e;
272*eb1d1641SHerbert Xu 	eth->h_dest[3] = 0;
273*eb1d1641SHerbert Xu 	eth->h_dest[4] = 0;
274*eb1d1641SHerbert Xu 	eth->h_dest[5] = 1;
275*eb1d1641SHerbert Xu 	eth->h_proto = htons(ETH_P_IP);
276*eb1d1641SHerbert Xu 	skb_put(skb, sizeof(*eth));
277*eb1d1641SHerbert Xu 
278*eb1d1641SHerbert Xu 	skb_set_network_header(skb, skb->len);
279*eb1d1641SHerbert Xu 	iph = ip_hdr(skb);
280*eb1d1641SHerbert Xu 
281*eb1d1641SHerbert Xu 	iph->version = 4;
282*eb1d1641SHerbert Xu 	iph->ihl = 6;
283*eb1d1641SHerbert Xu 	iph->tos = 0xc0;
284*eb1d1641SHerbert Xu 	iph->tot_len = htons(sizeof(*iph) + sizeof(*ih) + 4);
285*eb1d1641SHerbert Xu 	iph->id = 0;
286*eb1d1641SHerbert Xu 	iph->frag_off = htons(IP_DF);
287*eb1d1641SHerbert Xu 	iph->ttl = 1;
288*eb1d1641SHerbert Xu 	iph->protocol = IPPROTO_IGMP;
289*eb1d1641SHerbert Xu 	iph->saddr = 0;
290*eb1d1641SHerbert Xu 	iph->daddr = htonl(INADDR_ALLHOSTS_GROUP);
291*eb1d1641SHerbert Xu 	((u8 *)&iph[1])[0] = IPOPT_RA;
292*eb1d1641SHerbert Xu 	((u8 *)&iph[1])[1] = 4;
293*eb1d1641SHerbert Xu 	((u8 *)&iph[1])[2] = 0;
294*eb1d1641SHerbert Xu 	((u8 *)&iph[1])[3] = 0;
295*eb1d1641SHerbert Xu 	ip_send_check(iph);
296*eb1d1641SHerbert Xu 	skb_put(skb, 24);
297*eb1d1641SHerbert Xu 
298*eb1d1641SHerbert Xu 	skb_set_transport_header(skb, skb->len);
299*eb1d1641SHerbert Xu 	ih = igmp_hdr(skb);
300*eb1d1641SHerbert Xu 	ih->type = IGMP_HOST_MEMBERSHIP_QUERY;
301*eb1d1641SHerbert Xu 	ih->code = (group ? br->multicast_last_member_interval :
302*eb1d1641SHerbert Xu 			    br->multicast_query_response_interval) /
303*eb1d1641SHerbert Xu 		   (HZ / IGMP_TIMER_SCALE);
304*eb1d1641SHerbert Xu 	ih->group = group;
305*eb1d1641SHerbert Xu 	ih->csum = 0;
306*eb1d1641SHerbert Xu 	ih->csum = ip_compute_csum((void *)ih, sizeof(struct igmphdr));
307*eb1d1641SHerbert Xu 	skb_put(skb, sizeof(*ih));
308*eb1d1641SHerbert Xu 
309*eb1d1641SHerbert Xu 	__skb_pull(skb, sizeof(*eth));
310*eb1d1641SHerbert Xu 
311*eb1d1641SHerbert Xu out:
312*eb1d1641SHerbert Xu 	return skb;
313*eb1d1641SHerbert Xu }
314*eb1d1641SHerbert Xu 
315*eb1d1641SHerbert Xu static void br_multicast_send_group_query(struct net_bridge_mdb_entry *mp)
316*eb1d1641SHerbert Xu {
317*eb1d1641SHerbert Xu 	struct net_bridge *br = mp->br;
318*eb1d1641SHerbert Xu 	struct sk_buff *skb;
319*eb1d1641SHerbert Xu 
320*eb1d1641SHerbert Xu 	skb = br_multicast_alloc_query(br, mp->addr);
321*eb1d1641SHerbert Xu 	if (!skb)
322*eb1d1641SHerbert Xu 		goto timer;
323*eb1d1641SHerbert Xu 
324*eb1d1641SHerbert Xu 	netif_rx(skb);
325*eb1d1641SHerbert Xu 
326*eb1d1641SHerbert Xu timer:
327*eb1d1641SHerbert Xu 	if (++mp->queries_sent < br->multicast_last_member_count)
328*eb1d1641SHerbert Xu 		mod_timer(&mp->query_timer,
329*eb1d1641SHerbert Xu 			  jiffies + br->multicast_last_member_interval);
330*eb1d1641SHerbert Xu }
331*eb1d1641SHerbert Xu 
332*eb1d1641SHerbert Xu static void br_multicast_group_query_expired(unsigned long data)
333*eb1d1641SHerbert Xu {
334*eb1d1641SHerbert Xu 	struct net_bridge_mdb_entry *mp = (void *)data;
335*eb1d1641SHerbert Xu 	struct net_bridge *br = mp->br;
336*eb1d1641SHerbert Xu 
337*eb1d1641SHerbert Xu 	spin_lock(&br->multicast_lock);
338*eb1d1641SHerbert Xu 	if (!netif_running(br->dev) || hlist_unhashed(&mp->mglist) ||
339*eb1d1641SHerbert Xu 	    mp->queries_sent >= br->multicast_last_member_count)
340*eb1d1641SHerbert Xu 		goto out;
341*eb1d1641SHerbert Xu 
342*eb1d1641SHerbert Xu 	br_multicast_send_group_query(mp);
343*eb1d1641SHerbert Xu 
344*eb1d1641SHerbert Xu out:
345*eb1d1641SHerbert Xu 	spin_unlock(&br->multicast_lock);
346*eb1d1641SHerbert Xu }
347*eb1d1641SHerbert Xu 
348*eb1d1641SHerbert Xu static void br_multicast_send_port_group_query(struct net_bridge_port_group *pg)
349*eb1d1641SHerbert Xu {
350*eb1d1641SHerbert Xu 	struct net_bridge_port *port = pg->port;
351*eb1d1641SHerbert Xu 	struct net_bridge *br = port->br;
352*eb1d1641SHerbert Xu 	struct sk_buff *skb;
353*eb1d1641SHerbert Xu 
354*eb1d1641SHerbert Xu 	skb = br_multicast_alloc_query(br, pg->addr);
355*eb1d1641SHerbert Xu 	if (!skb)
356*eb1d1641SHerbert Xu 		goto timer;
357*eb1d1641SHerbert Xu 
358*eb1d1641SHerbert Xu 	br_deliver(port, skb);
359*eb1d1641SHerbert Xu 
360*eb1d1641SHerbert Xu timer:
361*eb1d1641SHerbert Xu 	if (++pg->queries_sent < br->multicast_last_member_count)
362*eb1d1641SHerbert Xu 		mod_timer(&pg->query_timer,
363*eb1d1641SHerbert Xu 			  jiffies + br->multicast_last_member_interval);
364*eb1d1641SHerbert Xu }
365*eb1d1641SHerbert Xu 
366*eb1d1641SHerbert Xu static void br_multicast_port_group_query_expired(unsigned long data)
367*eb1d1641SHerbert Xu {
368*eb1d1641SHerbert Xu 	struct net_bridge_port_group *pg = (void *)data;
369*eb1d1641SHerbert Xu 	struct net_bridge_port *port = pg->port;
370*eb1d1641SHerbert Xu 	struct net_bridge *br = port->br;
371*eb1d1641SHerbert Xu 
372*eb1d1641SHerbert Xu 	spin_lock(&br->multicast_lock);
373*eb1d1641SHerbert Xu 	if (!netif_running(br->dev) || hlist_unhashed(&pg->mglist) ||
374*eb1d1641SHerbert Xu 	    pg->queries_sent >= br->multicast_last_member_count)
375*eb1d1641SHerbert Xu 		goto out;
376*eb1d1641SHerbert Xu 
377*eb1d1641SHerbert Xu 	br_multicast_send_port_group_query(pg);
378*eb1d1641SHerbert Xu 
379*eb1d1641SHerbert Xu out:
380*eb1d1641SHerbert Xu 	spin_unlock(&br->multicast_lock);
381*eb1d1641SHerbert Xu }
382*eb1d1641SHerbert Xu 
383*eb1d1641SHerbert Xu static struct net_bridge_mdb_entry *br_multicast_get_group(
384*eb1d1641SHerbert Xu 	struct net_bridge *br, struct net_bridge_port *port, __be32 group,
385*eb1d1641SHerbert Xu 	int hash)
386*eb1d1641SHerbert Xu {
387*eb1d1641SHerbert Xu 	struct net_bridge_mdb_htable *mdb = br->mdb;
388*eb1d1641SHerbert Xu 	struct net_bridge_mdb_entry *mp;
389*eb1d1641SHerbert Xu 	struct hlist_node *p;
390*eb1d1641SHerbert Xu 	unsigned count = 0;
391*eb1d1641SHerbert Xu 	unsigned max;
392*eb1d1641SHerbert Xu 	int elasticity;
393*eb1d1641SHerbert Xu 	int err;
394*eb1d1641SHerbert Xu 
395*eb1d1641SHerbert Xu 	hlist_for_each_entry(mp, p, &mdb->mhash[hash], hlist[mdb->ver]) {
396*eb1d1641SHerbert Xu 		count++;
397*eb1d1641SHerbert Xu 		if (unlikely(group == mp->addr)) {
398*eb1d1641SHerbert Xu 			return mp;
399*eb1d1641SHerbert Xu 		}
400*eb1d1641SHerbert Xu 	}
401*eb1d1641SHerbert Xu 
402*eb1d1641SHerbert Xu 	elasticity = 0;
403*eb1d1641SHerbert Xu 	max = mdb->max;
404*eb1d1641SHerbert Xu 
405*eb1d1641SHerbert Xu 	if (unlikely(count > br->hash_elasticity && count)) {
406*eb1d1641SHerbert Xu 		if (net_ratelimit())
407*eb1d1641SHerbert Xu 			printk(KERN_INFO "%s: Multicast hash table "
408*eb1d1641SHerbert Xu 			       "chain limit reached: %s\n",
409*eb1d1641SHerbert Xu 			       br->dev->name, port ? port->dev->name :
410*eb1d1641SHerbert Xu 						     br->dev->name);
411*eb1d1641SHerbert Xu 
412*eb1d1641SHerbert Xu 		elasticity = br->hash_elasticity;
413*eb1d1641SHerbert Xu 	}
414*eb1d1641SHerbert Xu 
415*eb1d1641SHerbert Xu 	if (mdb->size >= max) {
416*eb1d1641SHerbert Xu 		max *= 2;
417*eb1d1641SHerbert Xu 		if (unlikely(max >= br->hash_max)) {
418*eb1d1641SHerbert Xu 			printk(KERN_WARNING "%s: Multicast hash table maximum "
419*eb1d1641SHerbert Xu 			       "reached, disabling snooping: %s, %d\n",
420*eb1d1641SHerbert Xu 			       br->dev->name, port ? port->dev->name :
421*eb1d1641SHerbert Xu 						     br->dev->name,
422*eb1d1641SHerbert Xu 			       max);
423*eb1d1641SHerbert Xu 			err = -E2BIG;
424*eb1d1641SHerbert Xu disable:
425*eb1d1641SHerbert Xu 			br->multicast_disabled = 1;
426*eb1d1641SHerbert Xu 			goto err;
427*eb1d1641SHerbert Xu 		}
428*eb1d1641SHerbert Xu 	}
429*eb1d1641SHerbert Xu 
430*eb1d1641SHerbert Xu 	if (max > mdb->max || elasticity) {
431*eb1d1641SHerbert Xu 		if (mdb->old) {
432*eb1d1641SHerbert Xu 			if (net_ratelimit())
433*eb1d1641SHerbert Xu 				printk(KERN_INFO "%s: Multicast hash table "
434*eb1d1641SHerbert Xu 				       "on fire: %s\n",
435*eb1d1641SHerbert Xu 				       br->dev->name, port ? port->dev->name :
436*eb1d1641SHerbert Xu 							     br->dev->name);
437*eb1d1641SHerbert Xu 			err = -EEXIST;
438*eb1d1641SHerbert Xu 			goto err;
439*eb1d1641SHerbert Xu 		}
440*eb1d1641SHerbert Xu 
441*eb1d1641SHerbert Xu 		err = br_mdb_rehash(&br->mdb, max, elasticity);
442*eb1d1641SHerbert Xu 		if (err) {
443*eb1d1641SHerbert Xu 			printk(KERN_WARNING "%s: Cannot rehash multicast "
444*eb1d1641SHerbert Xu 			       "hash table, disabling snooping: "
445*eb1d1641SHerbert Xu 			       "%s, %d, %d\n",
446*eb1d1641SHerbert Xu 			       br->dev->name, port ? port->dev->name :
447*eb1d1641SHerbert Xu 						     br->dev->name,
448*eb1d1641SHerbert Xu 			       mdb->size, err);
449*eb1d1641SHerbert Xu 			goto disable;
450*eb1d1641SHerbert Xu 		}
451*eb1d1641SHerbert Xu 
452*eb1d1641SHerbert Xu 		err = -EAGAIN;
453*eb1d1641SHerbert Xu 		goto err;
454*eb1d1641SHerbert Xu 	}
455*eb1d1641SHerbert Xu 
456*eb1d1641SHerbert Xu 	return NULL;
457*eb1d1641SHerbert Xu 
458*eb1d1641SHerbert Xu err:
459*eb1d1641SHerbert Xu 	mp = ERR_PTR(err);
460*eb1d1641SHerbert Xu 	return mp;
461*eb1d1641SHerbert Xu }
462*eb1d1641SHerbert Xu 
463*eb1d1641SHerbert Xu static struct net_bridge_mdb_entry *br_multicast_new_group(
464*eb1d1641SHerbert Xu 	struct net_bridge *br, struct net_bridge_port *port, __be32 group)
465*eb1d1641SHerbert Xu {
466*eb1d1641SHerbert Xu 	struct net_bridge_mdb_htable *mdb = br->mdb;
467*eb1d1641SHerbert Xu 	struct net_bridge_mdb_entry *mp;
468*eb1d1641SHerbert Xu 	int hash;
469*eb1d1641SHerbert Xu 
470*eb1d1641SHerbert Xu 	if (!mdb) {
471*eb1d1641SHerbert Xu 		if (br_mdb_rehash(&br->mdb, BR_HASH_SIZE, 0))
472*eb1d1641SHerbert Xu 			return NULL;
473*eb1d1641SHerbert Xu 		goto rehash;
474*eb1d1641SHerbert Xu 	}
475*eb1d1641SHerbert Xu 
476*eb1d1641SHerbert Xu 	hash = br_ip_hash(mdb, group);
477*eb1d1641SHerbert Xu 	mp = br_multicast_get_group(br, port, group, hash);
478*eb1d1641SHerbert Xu 	switch (PTR_ERR(mp)) {
479*eb1d1641SHerbert Xu 	case 0:
480*eb1d1641SHerbert Xu 		break;
481*eb1d1641SHerbert Xu 
482*eb1d1641SHerbert Xu 	case -EAGAIN:
483*eb1d1641SHerbert Xu rehash:
484*eb1d1641SHerbert Xu 		mdb = br->mdb;
485*eb1d1641SHerbert Xu 		hash = br_ip_hash(mdb, group);
486*eb1d1641SHerbert Xu 		break;
487*eb1d1641SHerbert Xu 
488*eb1d1641SHerbert Xu 	default:
489*eb1d1641SHerbert Xu 		goto out;
490*eb1d1641SHerbert Xu 	}
491*eb1d1641SHerbert Xu 
492*eb1d1641SHerbert Xu 	mp = kzalloc(sizeof(*mp), GFP_ATOMIC);
493*eb1d1641SHerbert Xu 	if (unlikely(!mp))
494*eb1d1641SHerbert Xu 		goto out;
495*eb1d1641SHerbert Xu 
496*eb1d1641SHerbert Xu 	mp->br = br;
497*eb1d1641SHerbert Xu 	mp->addr = group;
498*eb1d1641SHerbert Xu 	setup_timer(&mp->timer, br_multicast_group_expired,
499*eb1d1641SHerbert Xu 		    (unsigned long)mp);
500*eb1d1641SHerbert Xu 	setup_timer(&mp->query_timer, br_multicast_group_query_expired,
501*eb1d1641SHerbert Xu 		    (unsigned long)mp);
502*eb1d1641SHerbert Xu 
503*eb1d1641SHerbert Xu 	hlist_add_head_rcu(&mp->hlist[mdb->ver], &mdb->mhash[hash]);
504*eb1d1641SHerbert Xu 	mdb->size++;
505*eb1d1641SHerbert Xu 
506*eb1d1641SHerbert Xu out:
507*eb1d1641SHerbert Xu 	return mp;
508*eb1d1641SHerbert Xu }
509*eb1d1641SHerbert Xu 
510*eb1d1641SHerbert Xu static int br_multicast_add_group(struct net_bridge *br,
511*eb1d1641SHerbert Xu 				  struct net_bridge_port *port, __be32 group)
512*eb1d1641SHerbert Xu {
513*eb1d1641SHerbert Xu 	struct net_bridge_mdb_entry *mp;
514*eb1d1641SHerbert Xu 	struct net_bridge_port_group *p;
515*eb1d1641SHerbert Xu 	struct net_bridge_port_group **pp;
516*eb1d1641SHerbert Xu 	unsigned long now = jiffies;
517*eb1d1641SHerbert Xu 	int err;
518*eb1d1641SHerbert Xu 
519*eb1d1641SHerbert Xu 	if (ipv4_is_local_multicast(group))
520*eb1d1641SHerbert Xu 		return 0;
521*eb1d1641SHerbert Xu 
522*eb1d1641SHerbert Xu 	spin_lock(&br->multicast_lock);
523*eb1d1641SHerbert Xu 	if (!netif_running(br->dev) ||
524*eb1d1641SHerbert Xu 	    (port && port->state == BR_STATE_DISABLED))
525*eb1d1641SHerbert Xu 		goto out;
526*eb1d1641SHerbert Xu 
527*eb1d1641SHerbert Xu 	mp = br_multicast_new_group(br, port, group);
528*eb1d1641SHerbert Xu 	err = PTR_ERR(mp);
529*eb1d1641SHerbert Xu 	if (unlikely(IS_ERR(mp) || !mp))
530*eb1d1641SHerbert Xu 		goto err;
531*eb1d1641SHerbert Xu 
532*eb1d1641SHerbert Xu 	if (!port) {
533*eb1d1641SHerbert Xu 		hlist_add_head(&mp->mglist, &br->mglist);
534*eb1d1641SHerbert Xu 		mod_timer(&mp->timer, now + br->multicast_membership_interval);
535*eb1d1641SHerbert Xu 		goto out;
536*eb1d1641SHerbert Xu 	}
537*eb1d1641SHerbert Xu 
538*eb1d1641SHerbert Xu 	for (pp = &mp->ports; (p = *pp); pp = &p->next) {
539*eb1d1641SHerbert Xu 		if (p->port == port)
540*eb1d1641SHerbert Xu 			goto found;
541*eb1d1641SHerbert Xu 		if ((unsigned long)p->port < (unsigned long)port)
542*eb1d1641SHerbert Xu 			break;
543*eb1d1641SHerbert Xu 	}
544*eb1d1641SHerbert Xu 
545*eb1d1641SHerbert Xu 	p = kzalloc(sizeof(*p), GFP_ATOMIC);
546*eb1d1641SHerbert Xu 	err = -ENOMEM;
547*eb1d1641SHerbert Xu 	if (unlikely(!p))
548*eb1d1641SHerbert Xu 		goto err;
549*eb1d1641SHerbert Xu 
550*eb1d1641SHerbert Xu 	p->addr = group;
551*eb1d1641SHerbert Xu 	p->port = port;
552*eb1d1641SHerbert Xu 	p->next = *pp;
553*eb1d1641SHerbert Xu 	hlist_add_head(&p->mglist, &port->mglist);
554*eb1d1641SHerbert Xu 	setup_timer(&p->timer, br_multicast_port_group_expired,
555*eb1d1641SHerbert Xu 		    (unsigned long)p);
556*eb1d1641SHerbert Xu 	setup_timer(&p->query_timer, br_multicast_port_group_query_expired,
557*eb1d1641SHerbert Xu 		    (unsigned long)p);
558*eb1d1641SHerbert Xu 
559*eb1d1641SHerbert Xu 	rcu_assign_pointer(*pp, p);
560*eb1d1641SHerbert Xu 
561*eb1d1641SHerbert Xu found:
562*eb1d1641SHerbert Xu 	mod_timer(&p->timer, now + br->multicast_membership_interval);
563*eb1d1641SHerbert Xu out:
564*eb1d1641SHerbert Xu 	err = 0;
565*eb1d1641SHerbert Xu 
566*eb1d1641SHerbert Xu err:
567*eb1d1641SHerbert Xu 	spin_unlock(&br->multicast_lock);
568*eb1d1641SHerbert Xu 	return err;
569*eb1d1641SHerbert Xu }
570*eb1d1641SHerbert Xu 
571*eb1d1641SHerbert Xu static void br_multicast_router_expired(unsigned long data)
572*eb1d1641SHerbert Xu {
573*eb1d1641SHerbert Xu 	struct net_bridge_port *port = (void *)data;
574*eb1d1641SHerbert Xu 	struct net_bridge *br = port->br;
575*eb1d1641SHerbert Xu 
576*eb1d1641SHerbert Xu 	spin_lock(&br->multicast_lock);
577*eb1d1641SHerbert Xu 	if (port->multicast_router != 1 ||
578*eb1d1641SHerbert Xu 	    timer_pending(&port->multicast_router_timer) ||
579*eb1d1641SHerbert Xu 	    hlist_unhashed(&port->rlist))
580*eb1d1641SHerbert Xu 		goto out;
581*eb1d1641SHerbert Xu 
582*eb1d1641SHerbert Xu 	hlist_del_init_rcu(&port->rlist);
583*eb1d1641SHerbert Xu 
584*eb1d1641SHerbert Xu out:
585*eb1d1641SHerbert Xu 	spin_unlock(&br->multicast_lock);
586*eb1d1641SHerbert Xu }
587*eb1d1641SHerbert Xu 
588*eb1d1641SHerbert Xu static void br_multicast_local_router_expired(unsigned long data)
589*eb1d1641SHerbert Xu {
590*eb1d1641SHerbert Xu }
591*eb1d1641SHerbert Xu 
592*eb1d1641SHerbert Xu static void br_multicast_send_query(struct net_bridge *br,
593*eb1d1641SHerbert Xu 				    struct net_bridge_port *port, u32 sent)
594*eb1d1641SHerbert Xu {
595*eb1d1641SHerbert Xu 	unsigned long time;
596*eb1d1641SHerbert Xu 	struct sk_buff *skb;
597*eb1d1641SHerbert Xu 
598*eb1d1641SHerbert Xu 	if (!netif_running(br->dev) || br->multicast_disabled ||
599*eb1d1641SHerbert Xu 	    timer_pending(&br->multicast_querier_timer))
600*eb1d1641SHerbert Xu 		return;
601*eb1d1641SHerbert Xu 
602*eb1d1641SHerbert Xu 	skb = br_multicast_alloc_query(br, 0);
603*eb1d1641SHerbert Xu 	if (!skb)
604*eb1d1641SHerbert Xu 		goto timer;
605*eb1d1641SHerbert Xu 
606*eb1d1641SHerbert Xu 	if (port) {
607*eb1d1641SHerbert Xu 		__skb_push(skb, sizeof(struct ethhdr));
608*eb1d1641SHerbert Xu 		skb->dev = port->dev;
609*eb1d1641SHerbert Xu 		NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_OUT, skb, NULL, skb->dev,
610*eb1d1641SHerbert Xu 			dev_queue_xmit);
611*eb1d1641SHerbert Xu 	} else
612*eb1d1641SHerbert Xu 		netif_rx(skb);
613*eb1d1641SHerbert Xu 
614*eb1d1641SHerbert Xu timer:
615*eb1d1641SHerbert Xu 	time = jiffies;
616*eb1d1641SHerbert Xu 	time += sent < br->multicast_startup_query_count ?
617*eb1d1641SHerbert Xu 		br->multicast_startup_query_interval :
618*eb1d1641SHerbert Xu 		br->multicast_query_interval;
619*eb1d1641SHerbert Xu 	mod_timer(port ? &port->multicast_query_timer :
620*eb1d1641SHerbert Xu 			 &br->multicast_query_timer, time);
621*eb1d1641SHerbert Xu }
622*eb1d1641SHerbert Xu 
623*eb1d1641SHerbert Xu static void br_multicast_port_query_expired(unsigned long data)
624*eb1d1641SHerbert Xu {
625*eb1d1641SHerbert Xu 	struct net_bridge_port *port = (void *)data;
626*eb1d1641SHerbert Xu 	struct net_bridge *br = port->br;
627*eb1d1641SHerbert Xu 
628*eb1d1641SHerbert Xu 	spin_lock(&br->multicast_lock);
629*eb1d1641SHerbert Xu 	if (port && (port->state == BR_STATE_DISABLED ||
630*eb1d1641SHerbert Xu 		     port->state == BR_STATE_BLOCKING))
631*eb1d1641SHerbert Xu 		goto out;
632*eb1d1641SHerbert Xu 
633*eb1d1641SHerbert Xu 	if (port->multicast_startup_queries_sent <
634*eb1d1641SHerbert Xu 	    br->multicast_startup_query_count)
635*eb1d1641SHerbert Xu 		port->multicast_startup_queries_sent++;
636*eb1d1641SHerbert Xu 
637*eb1d1641SHerbert Xu 	br_multicast_send_query(port->br, port,
638*eb1d1641SHerbert Xu 				port->multicast_startup_queries_sent);
639*eb1d1641SHerbert Xu 
640*eb1d1641SHerbert Xu out:
641*eb1d1641SHerbert Xu 	spin_unlock(&br->multicast_lock);
642*eb1d1641SHerbert Xu }
643*eb1d1641SHerbert Xu 
644*eb1d1641SHerbert Xu void br_multicast_add_port(struct net_bridge_port *port)
645*eb1d1641SHerbert Xu {
646*eb1d1641SHerbert Xu 	port->multicast_router = 1;
647*eb1d1641SHerbert Xu 
648*eb1d1641SHerbert Xu 	setup_timer(&port->multicast_router_timer, br_multicast_router_expired,
649*eb1d1641SHerbert Xu 		    (unsigned long)port);
650*eb1d1641SHerbert Xu 	setup_timer(&port->multicast_query_timer,
651*eb1d1641SHerbert Xu 		    br_multicast_port_query_expired, (unsigned long)port);
652*eb1d1641SHerbert Xu }
653*eb1d1641SHerbert Xu 
654*eb1d1641SHerbert Xu void br_multicast_del_port(struct net_bridge_port *port)
655*eb1d1641SHerbert Xu {
656*eb1d1641SHerbert Xu 	del_timer_sync(&port->multicast_router_timer);
657*eb1d1641SHerbert Xu }
658*eb1d1641SHerbert Xu 
659*eb1d1641SHerbert Xu void br_multicast_enable_port(struct net_bridge_port *port)
660*eb1d1641SHerbert Xu {
661*eb1d1641SHerbert Xu 	struct net_bridge *br = port->br;
662*eb1d1641SHerbert Xu 
663*eb1d1641SHerbert Xu 	spin_lock(&br->multicast_lock);
664*eb1d1641SHerbert Xu 	if (br->multicast_disabled || !netif_running(br->dev))
665*eb1d1641SHerbert Xu 		goto out;
666*eb1d1641SHerbert Xu 
667*eb1d1641SHerbert Xu 	port->multicast_startup_queries_sent = 0;
668*eb1d1641SHerbert Xu 
669*eb1d1641SHerbert Xu 	if (try_to_del_timer_sync(&port->multicast_query_timer) >= 0 ||
670*eb1d1641SHerbert Xu 	    del_timer(&port->multicast_query_timer))
671*eb1d1641SHerbert Xu 		mod_timer(&port->multicast_query_timer, jiffies);
672*eb1d1641SHerbert Xu 
673*eb1d1641SHerbert Xu out:
674*eb1d1641SHerbert Xu 	spin_unlock(&br->multicast_lock);
675*eb1d1641SHerbert Xu }
676*eb1d1641SHerbert Xu 
677*eb1d1641SHerbert Xu void br_multicast_disable_port(struct net_bridge_port *port)
678*eb1d1641SHerbert Xu {
679*eb1d1641SHerbert Xu 	struct net_bridge *br = port->br;
680*eb1d1641SHerbert Xu 	struct net_bridge_port_group *pg;
681*eb1d1641SHerbert Xu 	struct hlist_node *p, *n;
682*eb1d1641SHerbert Xu 
683*eb1d1641SHerbert Xu 	spin_lock(&br->multicast_lock);
684*eb1d1641SHerbert Xu 	hlist_for_each_entry_safe(pg, p, n, &port->mglist, mglist)
685*eb1d1641SHerbert Xu 		br_multicast_del_pg(br, pg);
686*eb1d1641SHerbert Xu 
687*eb1d1641SHerbert Xu 	if (!hlist_unhashed(&port->rlist))
688*eb1d1641SHerbert Xu 		hlist_del_init_rcu(&port->rlist);
689*eb1d1641SHerbert Xu 	del_timer(&port->multicast_router_timer);
690*eb1d1641SHerbert Xu 	del_timer(&port->multicast_query_timer);
691*eb1d1641SHerbert Xu 	spin_unlock(&br->multicast_lock);
692*eb1d1641SHerbert Xu }
693*eb1d1641SHerbert Xu 
694*eb1d1641SHerbert Xu static int br_multicast_igmp3_report(struct net_bridge *br,
695*eb1d1641SHerbert Xu 				     struct net_bridge_port *port,
696*eb1d1641SHerbert Xu 				     struct sk_buff *skb)
697*eb1d1641SHerbert Xu {
698*eb1d1641SHerbert Xu 	struct igmpv3_report *ih;
699*eb1d1641SHerbert Xu 	struct igmpv3_grec *grec;
700*eb1d1641SHerbert Xu 	int i;
701*eb1d1641SHerbert Xu 	int len;
702*eb1d1641SHerbert Xu 	int num;
703*eb1d1641SHerbert Xu 	int type;
704*eb1d1641SHerbert Xu 	int err = 0;
705*eb1d1641SHerbert Xu 	__be32 group;
706*eb1d1641SHerbert Xu 
707*eb1d1641SHerbert Xu 	if (!pskb_may_pull(skb, sizeof(*ih)))
708*eb1d1641SHerbert Xu 		return -EINVAL;
709*eb1d1641SHerbert Xu 
710*eb1d1641SHerbert Xu 	ih = igmpv3_report_hdr(skb);
711*eb1d1641SHerbert Xu 	num = ntohs(ih->ngrec);
712*eb1d1641SHerbert Xu 	len = sizeof(*ih);
713*eb1d1641SHerbert Xu 
714*eb1d1641SHerbert Xu 	for (i = 0; i < num; i++) {
715*eb1d1641SHerbert Xu 		len += sizeof(*grec);
716*eb1d1641SHerbert Xu 		if (!pskb_may_pull(skb, len))
717*eb1d1641SHerbert Xu 			return -EINVAL;
718*eb1d1641SHerbert Xu 
719*eb1d1641SHerbert Xu 		grec = (void *)(skb->data + len);
720*eb1d1641SHerbert Xu 		group = grec->grec_mca;
721*eb1d1641SHerbert Xu 		type = grec->grec_type;
722*eb1d1641SHerbert Xu 
723*eb1d1641SHerbert Xu 		len += grec->grec_nsrcs * 4;
724*eb1d1641SHerbert Xu 		if (!pskb_may_pull(skb, len))
725*eb1d1641SHerbert Xu 			return -EINVAL;
726*eb1d1641SHerbert Xu 
727*eb1d1641SHerbert Xu 		/* We treat this as an IGMPv2 report for now. */
728*eb1d1641SHerbert Xu 		switch (type) {
729*eb1d1641SHerbert Xu 		case IGMPV3_MODE_IS_INCLUDE:
730*eb1d1641SHerbert Xu 		case IGMPV3_MODE_IS_EXCLUDE:
731*eb1d1641SHerbert Xu 		case IGMPV3_CHANGE_TO_INCLUDE:
732*eb1d1641SHerbert Xu 		case IGMPV3_CHANGE_TO_EXCLUDE:
733*eb1d1641SHerbert Xu 		case IGMPV3_ALLOW_NEW_SOURCES:
734*eb1d1641SHerbert Xu 		case IGMPV3_BLOCK_OLD_SOURCES:
735*eb1d1641SHerbert Xu 			break;
736*eb1d1641SHerbert Xu 
737*eb1d1641SHerbert Xu 		default:
738*eb1d1641SHerbert Xu 			continue;
739*eb1d1641SHerbert Xu 		}
740*eb1d1641SHerbert Xu 
741*eb1d1641SHerbert Xu 		err = br_multicast_add_group(br, port, group);
742*eb1d1641SHerbert Xu 		if (err)
743*eb1d1641SHerbert Xu 			break;
744*eb1d1641SHerbert Xu 	}
745*eb1d1641SHerbert Xu 
746*eb1d1641SHerbert Xu 	return err;
747*eb1d1641SHerbert Xu }
748*eb1d1641SHerbert Xu 
749*eb1d1641SHerbert Xu static void br_multicast_mark_router(struct net_bridge *br,
750*eb1d1641SHerbert Xu 				     struct net_bridge_port *port)
751*eb1d1641SHerbert Xu {
752*eb1d1641SHerbert Xu 	unsigned long now = jiffies;
753*eb1d1641SHerbert Xu 	struct hlist_node *p;
754*eb1d1641SHerbert Xu 	struct hlist_node **h;
755*eb1d1641SHerbert Xu 
756*eb1d1641SHerbert Xu 	if (!port) {
757*eb1d1641SHerbert Xu 		if (br->multicast_router == 1)
758*eb1d1641SHerbert Xu 			mod_timer(&br->multicast_router_timer,
759*eb1d1641SHerbert Xu 				  now + br->multicast_querier_interval);
760*eb1d1641SHerbert Xu 		return;
761*eb1d1641SHerbert Xu 	}
762*eb1d1641SHerbert Xu 
763*eb1d1641SHerbert Xu 	if (port->multicast_router != 1)
764*eb1d1641SHerbert Xu 		return;
765*eb1d1641SHerbert Xu 
766*eb1d1641SHerbert Xu 	if (!hlist_unhashed(&port->rlist))
767*eb1d1641SHerbert Xu 		goto timer;
768*eb1d1641SHerbert Xu 
769*eb1d1641SHerbert Xu 	for (h = &br->router_list.first;
770*eb1d1641SHerbert Xu 	     (p = *h) &&
771*eb1d1641SHerbert Xu 	     (unsigned long)container_of(p, struct net_bridge_port, rlist) >
772*eb1d1641SHerbert Xu 	     (unsigned long)port;
773*eb1d1641SHerbert Xu 	     h = &p->next)
774*eb1d1641SHerbert Xu 		;
775*eb1d1641SHerbert Xu 
776*eb1d1641SHerbert Xu 	port->rlist.pprev = h;
777*eb1d1641SHerbert Xu 	port->rlist.next = p;
778*eb1d1641SHerbert Xu 	rcu_assign_pointer(*h, &port->rlist);
779*eb1d1641SHerbert Xu 	if (p)
780*eb1d1641SHerbert Xu 		p->pprev = &port->rlist.next;
781*eb1d1641SHerbert Xu 
782*eb1d1641SHerbert Xu timer:
783*eb1d1641SHerbert Xu 	mod_timer(&port->multicast_router_timer,
784*eb1d1641SHerbert Xu 		  now + br->multicast_querier_interval);
785*eb1d1641SHerbert Xu }
786*eb1d1641SHerbert Xu 
787*eb1d1641SHerbert Xu static void br_multicast_query_received(struct net_bridge *br,
788*eb1d1641SHerbert Xu 					struct net_bridge_port *port,
789*eb1d1641SHerbert Xu 					__be32 saddr)
790*eb1d1641SHerbert Xu {
791*eb1d1641SHerbert Xu 	if (saddr)
792*eb1d1641SHerbert Xu 		mod_timer(&br->multicast_querier_timer,
793*eb1d1641SHerbert Xu 			  jiffies + br->multicast_querier_interval);
794*eb1d1641SHerbert Xu 	else if (timer_pending(&br->multicast_querier_timer))
795*eb1d1641SHerbert Xu 		return;
796*eb1d1641SHerbert Xu 
797*eb1d1641SHerbert Xu 	br_multicast_mark_router(br, port);
798*eb1d1641SHerbert Xu }
799*eb1d1641SHerbert Xu 
800*eb1d1641SHerbert Xu static int br_multicast_query(struct net_bridge *br,
801*eb1d1641SHerbert Xu 			      struct net_bridge_port *port,
802*eb1d1641SHerbert Xu 			      struct sk_buff *skb)
803*eb1d1641SHerbert Xu {
804*eb1d1641SHerbert Xu 	struct iphdr *iph = ip_hdr(skb);
805*eb1d1641SHerbert Xu 	struct igmphdr *ih = igmp_hdr(skb);
806*eb1d1641SHerbert Xu 	struct net_bridge_mdb_entry *mp;
807*eb1d1641SHerbert Xu 	struct igmpv3_query *ih3;
808*eb1d1641SHerbert Xu 	struct net_bridge_port_group *p;
809*eb1d1641SHerbert Xu 	struct net_bridge_port_group **pp;
810*eb1d1641SHerbert Xu 	unsigned long max_delay;
811*eb1d1641SHerbert Xu 	unsigned long now = jiffies;
812*eb1d1641SHerbert Xu 	__be32 group;
813*eb1d1641SHerbert Xu 
814*eb1d1641SHerbert Xu 	spin_lock(&br->multicast_lock);
815*eb1d1641SHerbert Xu 	if (!netif_running(br->dev) ||
816*eb1d1641SHerbert Xu 	    (port && port->state == BR_STATE_DISABLED))
817*eb1d1641SHerbert Xu 		goto out;
818*eb1d1641SHerbert Xu 
819*eb1d1641SHerbert Xu 	br_multicast_query_received(br, port, iph->saddr);
820*eb1d1641SHerbert Xu 
821*eb1d1641SHerbert Xu 	group = ih->group;
822*eb1d1641SHerbert Xu 
823*eb1d1641SHerbert Xu 	if (skb->len == sizeof(*ih)) {
824*eb1d1641SHerbert Xu 		max_delay = ih->code * (HZ / IGMP_TIMER_SCALE);
825*eb1d1641SHerbert Xu 
826*eb1d1641SHerbert Xu 		if (!max_delay) {
827*eb1d1641SHerbert Xu 			max_delay = 10 * HZ;
828*eb1d1641SHerbert Xu 			group = 0;
829*eb1d1641SHerbert Xu 		}
830*eb1d1641SHerbert Xu 	} else {
831*eb1d1641SHerbert Xu 		if (!pskb_may_pull(skb, sizeof(struct igmpv3_query)))
832*eb1d1641SHerbert Xu 			return -EINVAL;
833*eb1d1641SHerbert Xu 
834*eb1d1641SHerbert Xu 		ih3 = igmpv3_query_hdr(skb);
835*eb1d1641SHerbert Xu 		if (ih3->nsrcs)
836*eb1d1641SHerbert Xu 			return 0;
837*eb1d1641SHerbert Xu 
838*eb1d1641SHerbert Xu 		max_delay = ih3->code ? 1 :
839*eb1d1641SHerbert Xu 			    IGMPV3_MRC(ih3->code) * (HZ / IGMP_TIMER_SCALE);
840*eb1d1641SHerbert Xu 	}
841*eb1d1641SHerbert Xu 
842*eb1d1641SHerbert Xu 	if (!group)
843*eb1d1641SHerbert Xu 		goto out;
844*eb1d1641SHerbert Xu 
845*eb1d1641SHerbert Xu 	mp = br_mdb_ip_get(br->mdb, group);
846*eb1d1641SHerbert Xu 	if (!mp)
847*eb1d1641SHerbert Xu 		goto out;
848*eb1d1641SHerbert Xu 
849*eb1d1641SHerbert Xu 	max_delay *= br->multicast_last_member_count;
850*eb1d1641SHerbert Xu 
851*eb1d1641SHerbert Xu 	if (!hlist_unhashed(&mp->mglist) &&
852*eb1d1641SHerbert Xu 	    (timer_pending(&mp->timer) ?
853*eb1d1641SHerbert Xu 	     time_after(mp->timer.expires, now + max_delay) :
854*eb1d1641SHerbert Xu 	     try_to_del_timer_sync(&mp->timer) >= 0))
855*eb1d1641SHerbert Xu 		mod_timer(&mp->timer, now + max_delay);
856*eb1d1641SHerbert Xu 
857*eb1d1641SHerbert Xu 	for (pp = &mp->ports; (p = *pp); pp = &p->next) {
858*eb1d1641SHerbert Xu 		if (timer_pending(&p->timer) ?
859*eb1d1641SHerbert Xu 		    time_after(p->timer.expires, now + max_delay) :
860*eb1d1641SHerbert Xu 		    try_to_del_timer_sync(&p->timer) >= 0)
861*eb1d1641SHerbert Xu 			mod_timer(&mp->timer, now + max_delay);
862*eb1d1641SHerbert Xu 	}
863*eb1d1641SHerbert Xu 
864*eb1d1641SHerbert Xu out:
865*eb1d1641SHerbert Xu 	spin_unlock(&br->multicast_lock);
866*eb1d1641SHerbert Xu 	return 0;
867*eb1d1641SHerbert Xu }
868*eb1d1641SHerbert Xu 
869*eb1d1641SHerbert Xu static void br_multicast_leave_group(struct net_bridge *br,
870*eb1d1641SHerbert Xu 				     struct net_bridge_port *port,
871*eb1d1641SHerbert Xu 				     __be32 group)
872*eb1d1641SHerbert Xu {
873*eb1d1641SHerbert Xu 	struct net_bridge_mdb_htable *mdb;
874*eb1d1641SHerbert Xu 	struct net_bridge_mdb_entry *mp;
875*eb1d1641SHerbert Xu 	struct net_bridge_port_group *p;
876*eb1d1641SHerbert Xu 	unsigned long now;
877*eb1d1641SHerbert Xu 	unsigned long time;
878*eb1d1641SHerbert Xu 
879*eb1d1641SHerbert Xu 	if (ipv4_is_local_multicast(group))
880*eb1d1641SHerbert Xu 		return;
881*eb1d1641SHerbert Xu 
882*eb1d1641SHerbert Xu 	spin_lock(&br->multicast_lock);
883*eb1d1641SHerbert Xu 	if (!netif_running(br->dev) ||
884*eb1d1641SHerbert Xu 	    (port && port->state == BR_STATE_DISABLED) ||
885*eb1d1641SHerbert Xu 	    timer_pending(&br->multicast_querier_timer))
886*eb1d1641SHerbert Xu 		goto out;
887*eb1d1641SHerbert Xu 
888*eb1d1641SHerbert Xu 	mdb = br->mdb;
889*eb1d1641SHerbert Xu 	mp = br_mdb_ip_get(mdb, group);
890*eb1d1641SHerbert Xu 	if (!mp)
891*eb1d1641SHerbert Xu 		goto out;
892*eb1d1641SHerbert Xu 
893*eb1d1641SHerbert Xu 	now = jiffies;
894*eb1d1641SHerbert Xu 	time = now + br->multicast_last_member_count *
895*eb1d1641SHerbert Xu 		     br->multicast_last_member_interval;
896*eb1d1641SHerbert Xu 
897*eb1d1641SHerbert Xu 	if (!port) {
898*eb1d1641SHerbert Xu 		if (!hlist_unhashed(&mp->mglist) &&
899*eb1d1641SHerbert Xu 		    (timer_pending(&mp->timer) ?
900*eb1d1641SHerbert Xu 		     time_after(mp->timer.expires, time) :
901*eb1d1641SHerbert Xu 		     try_to_del_timer_sync(&mp->timer) >= 0)) {
902*eb1d1641SHerbert Xu 			mod_timer(&mp->timer, time);
903*eb1d1641SHerbert Xu 
904*eb1d1641SHerbert Xu 			mp->queries_sent = 0;
905*eb1d1641SHerbert Xu 			mod_timer(&mp->query_timer, now);
906*eb1d1641SHerbert Xu 		}
907*eb1d1641SHerbert Xu 
908*eb1d1641SHerbert Xu 		goto out;
909*eb1d1641SHerbert Xu 	}
910*eb1d1641SHerbert Xu 
911*eb1d1641SHerbert Xu 	for (p = mp->ports; p; p = p->next) {
912*eb1d1641SHerbert Xu 		if (p->port != port)
913*eb1d1641SHerbert Xu 			continue;
914*eb1d1641SHerbert Xu 
915*eb1d1641SHerbert Xu 		if (!hlist_unhashed(&p->mglist) &&
916*eb1d1641SHerbert Xu 		    (timer_pending(&p->timer) ?
917*eb1d1641SHerbert Xu 		     time_after(p->timer.expires, time) :
918*eb1d1641SHerbert Xu 		     try_to_del_timer_sync(&p->timer) >= 0)) {
919*eb1d1641SHerbert Xu 			mod_timer(&p->timer, time);
920*eb1d1641SHerbert Xu 
921*eb1d1641SHerbert Xu 			p->queries_sent = 0;
922*eb1d1641SHerbert Xu 			mod_timer(&p->query_timer, now);
923*eb1d1641SHerbert Xu 		}
924*eb1d1641SHerbert Xu 
925*eb1d1641SHerbert Xu 		break;
926*eb1d1641SHerbert Xu 	}
927*eb1d1641SHerbert Xu 
928*eb1d1641SHerbert Xu out:
929*eb1d1641SHerbert Xu 	spin_unlock(&br->multicast_lock);
930*eb1d1641SHerbert Xu }
931*eb1d1641SHerbert Xu 
932*eb1d1641SHerbert Xu static int br_multicast_ipv4_rcv(struct net_bridge *br,
933*eb1d1641SHerbert Xu 				 struct net_bridge_port *port,
934*eb1d1641SHerbert Xu 				 struct sk_buff *skb)
935*eb1d1641SHerbert Xu {
936*eb1d1641SHerbert Xu 	struct sk_buff *skb2 = skb;
937*eb1d1641SHerbert Xu 	struct iphdr *iph;
938*eb1d1641SHerbert Xu 	struct igmphdr *ih;
939*eb1d1641SHerbert Xu 	unsigned len;
940*eb1d1641SHerbert Xu 	unsigned offset;
941*eb1d1641SHerbert Xu 	int err;
942*eb1d1641SHerbert Xu 
943*eb1d1641SHerbert Xu 	BR_INPUT_SKB_CB(skb)->igmp = 0;
944*eb1d1641SHerbert Xu 	BR_INPUT_SKB_CB(skb)->mrouters_only = 0;
945*eb1d1641SHerbert Xu 
946*eb1d1641SHerbert Xu 	/* We treat OOM as packet loss for now. */
947*eb1d1641SHerbert Xu 	if (!pskb_may_pull(skb, sizeof(*iph)))
948*eb1d1641SHerbert Xu 		return -EINVAL;
949*eb1d1641SHerbert Xu 
950*eb1d1641SHerbert Xu 	iph = ip_hdr(skb);
951*eb1d1641SHerbert Xu 
952*eb1d1641SHerbert Xu 	if (iph->ihl < 5 || iph->version != 4)
953*eb1d1641SHerbert Xu 		return -EINVAL;
954*eb1d1641SHerbert Xu 
955*eb1d1641SHerbert Xu 	if (!pskb_may_pull(skb, ip_hdrlen(skb)))
956*eb1d1641SHerbert Xu 		return -EINVAL;
957*eb1d1641SHerbert Xu 
958*eb1d1641SHerbert Xu 	iph = ip_hdr(skb);
959*eb1d1641SHerbert Xu 
960*eb1d1641SHerbert Xu 	if (unlikely(ip_fast_csum((u8 *)iph, iph->ihl)))
961*eb1d1641SHerbert Xu 		return -EINVAL;
962*eb1d1641SHerbert Xu 
963*eb1d1641SHerbert Xu 	if (iph->protocol != IPPROTO_IGMP)
964*eb1d1641SHerbert Xu 		return 0;
965*eb1d1641SHerbert Xu 
966*eb1d1641SHerbert Xu 	len = ntohs(iph->tot_len);
967*eb1d1641SHerbert Xu 	if (skb->len < len || len < ip_hdrlen(skb))
968*eb1d1641SHerbert Xu 		return -EINVAL;
969*eb1d1641SHerbert Xu 
970*eb1d1641SHerbert Xu 	if (skb->len > len) {
971*eb1d1641SHerbert Xu 		skb2 = skb_clone(skb, GFP_ATOMIC);
972*eb1d1641SHerbert Xu 		if (!skb2)
973*eb1d1641SHerbert Xu 			return -ENOMEM;
974*eb1d1641SHerbert Xu 
975*eb1d1641SHerbert Xu 		err = pskb_trim_rcsum(skb2, len);
976*eb1d1641SHerbert Xu 		if (err)
977*eb1d1641SHerbert Xu 			return err;
978*eb1d1641SHerbert Xu 	}
979*eb1d1641SHerbert Xu 
980*eb1d1641SHerbert Xu 	len -= ip_hdrlen(skb2);
981*eb1d1641SHerbert Xu 	offset = skb_network_offset(skb2) + ip_hdrlen(skb2);
982*eb1d1641SHerbert Xu 	__skb_pull(skb2, offset);
983*eb1d1641SHerbert Xu 	skb_reset_transport_header(skb2);
984*eb1d1641SHerbert Xu 
985*eb1d1641SHerbert Xu 	err = -EINVAL;
986*eb1d1641SHerbert Xu 	if (!pskb_may_pull(skb2, sizeof(*ih)))
987*eb1d1641SHerbert Xu 		goto out;
988*eb1d1641SHerbert Xu 
989*eb1d1641SHerbert Xu 	iph = ip_hdr(skb2);
990*eb1d1641SHerbert Xu 
991*eb1d1641SHerbert Xu 	switch (skb2->ip_summed) {
992*eb1d1641SHerbert Xu 	case CHECKSUM_COMPLETE:
993*eb1d1641SHerbert Xu 		if (!csum_fold(skb2->csum))
994*eb1d1641SHerbert Xu 			break;
995*eb1d1641SHerbert Xu 		/* fall through */
996*eb1d1641SHerbert Xu 	case CHECKSUM_NONE:
997*eb1d1641SHerbert Xu 		skb2->csum = 0;
998*eb1d1641SHerbert Xu 		if (skb_checksum_complete(skb2))
999*eb1d1641SHerbert Xu 			return -EINVAL;
1000*eb1d1641SHerbert Xu 	}
1001*eb1d1641SHerbert Xu 
1002*eb1d1641SHerbert Xu 	err = 0;
1003*eb1d1641SHerbert Xu 
1004*eb1d1641SHerbert Xu 	BR_INPUT_SKB_CB(skb)->igmp = 1;
1005*eb1d1641SHerbert Xu 	ih = igmp_hdr(skb2);
1006*eb1d1641SHerbert Xu 
1007*eb1d1641SHerbert Xu 	switch (ih->type) {
1008*eb1d1641SHerbert Xu 	case IGMP_HOST_MEMBERSHIP_REPORT:
1009*eb1d1641SHerbert Xu 	case IGMPV2_HOST_MEMBERSHIP_REPORT:
1010*eb1d1641SHerbert Xu 		BR_INPUT_SKB_CB(skb2)->mrouters_only = 1;
1011*eb1d1641SHerbert Xu 		err = br_multicast_add_group(br, port, ih->group);
1012*eb1d1641SHerbert Xu 		break;
1013*eb1d1641SHerbert Xu 	case IGMPV3_HOST_MEMBERSHIP_REPORT:
1014*eb1d1641SHerbert Xu 		err = br_multicast_igmp3_report(br, port, skb2);
1015*eb1d1641SHerbert Xu 		break;
1016*eb1d1641SHerbert Xu 	case IGMP_HOST_MEMBERSHIP_QUERY:
1017*eb1d1641SHerbert Xu 		err = br_multicast_query(br, port, skb2);
1018*eb1d1641SHerbert Xu 		break;
1019*eb1d1641SHerbert Xu 	case IGMP_HOST_LEAVE_MESSAGE:
1020*eb1d1641SHerbert Xu 		br_multicast_leave_group(br, port, ih->group);
1021*eb1d1641SHerbert Xu 		break;
1022*eb1d1641SHerbert Xu 	}
1023*eb1d1641SHerbert Xu 
1024*eb1d1641SHerbert Xu out:
1025*eb1d1641SHerbert Xu 	__skb_push(skb2, offset);
1026*eb1d1641SHerbert Xu 	if (skb2 != skb)
1027*eb1d1641SHerbert Xu 		kfree_skb(skb2);
1028*eb1d1641SHerbert Xu 	return err;
1029*eb1d1641SHerbert Xu }
1030*eb1d1641SHerbert Xu 
1031*eb1d1641SHerbert Xu int br_multicast_rcv(struct net_bridge *br, struct net_bridge_port *port,
1032*eb1d1641SHerbert Xu 		     struct sk_buff *skb)
1033*eb1d1641SHerbert Xu {
1034*eb1d1641SHerbert Xu 	if (br->multicast_disabled)
1035*eb1d1641SHerbert Xu 		return 0;
1036*eb1d1641SHerbert Xu 
1037*eb1d1641SHerbert Xu 	switch (skb->protocol) {
1038*eb1d1641SHerbert Xu 	case htons(ETH_P_IP):
1039*eb1d1641SHerbert Xu 		return br_multicast_ipv4_rcv(br, port, skb);
1040*eb1d1641SHerbert Xu 	}
1041*eb1d1641SHerbert Xu 
1042*eb1d1641SHerbert Xu 	return 0;
1043*eb1d1641SHerbert Xu }
1044*eb1d1641SHerbert Xu 
1045*eb1d1641SHerbert Xu static void br_multicast_query_expired(unsigned long data)
1046*eb1d1641SHerbert Xu {
1047*eb1d1641SHerbert Xu 	struct net_bridge *br = (void *)data;
1048*eb1d1641SHerbert Xu 
1049*eb1d1641SHerbert Xu 	spin_lock(&br->multicast_lock);
1050*eb1d1641SHerbert Xu 	if (br->multicast_startup_queries_sent <
1051*eb1d1641SHerbert Xu 	    br->multicast_startup_query_count)
1052*eb1d1641SHerbert Xu 		br->multicast_startup_queries_sent++;
1053*eb1d1641SHerbert Xu 
1054*eb1d1641SHerbert Xu 	br_multicast_send_query(br, NULL, br->multicast_startup_queries_sent);
1055*eb1d1641SHerbert Xu 
1056*eb1d1641SHerbert Xu 	spin_unlock(&br->multicast_lock);
1057*eb1d1641SHerbert Xu }
1058*eb1d1641SHerbert Xu 
1059*eb1d1641SHerbert Xu void br_multicast_init(struct net_bridge *br)
1060*eb1d1641SHerbert Xu {
1061*eb1d1641SHerbert Xu 	br->hash_elasticity = 4;
1062*eb1d1641SHerbert Xu 	br->hash_max = 512;
1063*eb1d1641SHerbert Xu 
1064*eb1d1641SHerbert Xu 	br->multicast_router = 1;
1065*eb1d1641SHerbert Xu 	br->multicast_last_member_count = 2;
1066*eb1d1641SHerbert Xu 	br->multicast_startup_query_count = 2;
1067*eb1d1641SHerbert Xu 
1068*eb1d1641SHerbert Xu 	br->multicast_last_member_interval = HZ;
1069*eb1d1641SHerbert Xu 	br->multicast_query_response_interval = 10 * HZ;
1070*eb1d1641SHerbert Xu 	br->multicast_startup_query_interval = 125 * HZ / 4;
1071*eb1d1641SHerbert Xu 	br->multicast_query_interval = 125 * HZ;
1072*eb1d1641SHerbert Xu 	br->multicast_querier_interval = 255 * HZ;
1073*eb1d1641SHerbert Xu 	br->multicast_membership_interval = 260 * HZ;
1074*eb1d1641SHerbert Xu 
1075*eb1d1641SHerbert Xu 	spin_lock_init(&br->multicast_lock);
1076*eb1d1641SHerbert Xu 	setup_timer(&br->multicast_router_timer,
1077*eb1d1641SHerbert Xu 		    br_multicast_local_router_expired, 0);
1078*eb1d1641SHerbert Xu 	setup_timer(&br->multicast_querier_timer,
1079*eb1d1641SHerbert Xu 		    br_multicast_local_router_expired, 0);
1080*eb1d1641SHerbert Xu 	setup_timer(&br->multicast_query_timer, br_multicast_query_expired,
1081*eb1d1641SHerbert Xu 		    (unsigned long)br);
1082*eb1d1641SHerbert Xu }
1083*eb1d1641SHerbert Xu 
1084*eb1d1641SHerbert Xu void br_multicast_open(struct net_bridge *br)
1085*eb1d1641SHerbert Xu {
1086*eb1d1641SHerbert Xu 	br->multicast_startup_queries_sent = 0;
1087*eb1d1641SHerbert Xu 
1088*eb1d1641SHerbert Xu 	if (br->multicast_disabled)
1089*eb1d1641SHerbert Xu 		return;
1090*eb1d1641SHerbert Xu 
1091*eb1d1641SHerbert Xu 	mod_timer(&br->multicast_query_timer, jiffies);
1092*eb1d1641SHerbert Xu }
1093*eb1d1641SHerbert Xu 
1094*eb1d1641SHerbert Xu void br_multicast_stop(struct net_bridge *br)
1095*eb1d1641SHerbert Xu {
1096*eb1d1641SHerbert Xu 	struct net_bridge_mdb_htable *mdb;
1097*eb1d1641SHerbert Xu 	struct net_bridge_mdb_entry *mp;
1098*eb1d1641SHerbert Xu 	struct hlist_node *p, *n;
1099*eb1d1641SHerbert Xu 	u32 ver;
1100*eb1d1641SHerbert Xu 	int i;
1101*eb1d1641SHerbert Xu 
1102*eb1d1641SHerbert Xu 	del_timer_sync(&br->multicast_router_timer);
1103*eb1d1641SHerbert Xu 	del_timer_sync(&br->multicast_querier_timer);
1104*eb1d1641SHerbert Xu 	del_timer_sync(&br->multicast_query_timer);
1105*eb1d1641SHerbert Xu 
1106*eb1d1641SHerbert Xu 	spin_lock_bh(&br->multicast_lock);
1107*eb1d1641SHerbert Xu 	mdb = br->mdb;
1108*eb1d1641SHerbert Xu 	if (!mdb)
1109*eb1d1641SHerbert Xu 		goto out;
1110*eb1d1641SHerbert Xu 
1111*eb1d1641SHerbert Xu 	br->mdb = NULL;
1112*eb1d1641SHerbert Xu 
1113*eb1d1641SHerbert Xu 	ver = mdb->ver;
1114*eb1d1641SHerbert Xu 	for (i = 0; i < mdb->max; i++) {
1115*eb1d1641SHerbert Xu 		hlist_for_each_entry_safe(mp, p, n, &mdb->mhash[i],
1116*eb1d1641SHerbert Xu 					  hlist[ver]) {
1117*eb1d1641SHerbert Xu 			del_timer(&mp->timer);
1118*eb1d1641SHerbert Xu 			del_timer(&mp->query_timer);
1119*eb1d1641SHerbert Xu 			call_rcu_bh(&mp->rcu, br_multicast_free_group);
1120*eb1d1641SHerbert Xu 		}
1121*eb1d1641SHerbert Xu 	}
1122*eb1d1641SHerbert Xu 
1123*eb1d1641SHerbert Xu 	if (mdb->old) {
1124*eb1d1641SHerbert Xu 		spin_unlock_bh(&br->multicast_lock);
1125*eb1d1641SHerbert Xu 		synchronize_rcu_bh();
1126*eb1d1641SHerbert Xu 		spin_lock_bh(&br->multicast_lock);
1127*eb1d1641SHerbert Xu 		WARN_ON(mdb->old);
1128*eb1d1641SHerbert Xu 	}
1129*eb1d1641SHerbert Xu 
1130*eb1d1641SHerbert Xu 	mdb->old = mdb;
1131*eb1d1641SHerbert Xu 	call_rcu_bh(&mdb->rcu, br_mdb_free);
1132*eb1d1641SHerbert Xu 
1133*eb1d1641SHerbert Xu out:
1134*eb1d1641SHerbert Xu 	spin_unlock_bh(&br->multicast_lock);
1135*eb1d1641SHerbert Xu }
1136