f303c3a09406a559d9686de118fd181005701888
[openwrt/svn-archive/archive.git] / target / linux / generic / patches-3.10 / 070-net_bridge_backports.patch
1 commit 3c3769e63301fd92fcaf51870c371583dd0282ce
2 Author: Linus Lüssing <linus.luessing@web.de>
3 Date: Wed Sep 4 02:13:39 2013 +0200
4
5 bridge: apply multicast snooping to IPv6 link-local, too
6
7 The multicast snooping code should have matured enough to be safely
8 applicable to IPv6 link-local multicast addresses (excluding the
9 link-local all nodes address, ff02::1), too.
10
11 Signed-off-by: Linus Lüssing <linus.luessing@web.de>
12 Signed-off-by: David S. Miller <davem@davemloft.net>
13
14 commit 8fad9c39f31f9ed7bf3526c43a4537b2fcf1a5d5
15 Author: Linus Lüssing <linus.luessing@web.de>
16 Date: Wed Sep 4 02:13:38 2013 +0200
17
18 bridge: prevent flooding IPv6 packets that do not have a listener
19
20 Currently if there is no listener for a certain group then IPv6 packets
21 for that group are flooded on all ports, even though there might be no
22 host and router interested in it on a port.
23
24 With this commit they are only forwarded to ports with a multicast
25 router.
26
27 Just like commit bd4265fe36 ("bridge: Only flood unregistered groups
28 to routers") did for IPv4, let's do the same for IPv6 with the same
29 reasoning.
30
31 Signed-off-by: Linus Lüssing <linus.luessing@web.de>
32 Signed-off-by: David S. Miller <davem@davemloft.net>
33
34 commit cc0fdd802859eaeb00e1c87dbb655594bed2844c
35 Author: Linus Lüssing <linus.luessing@web.de>
36 Date: Fri Aug 30 17:28:17 2013 +0200
37
38 bridge: separate querier and query timer into IGMP/IPv4 and MLD/IPv6 ones
39
40 Currently we would still potentially suffer multicast packet loss if there
41 is just either an IGMP or an MLD querier: For the former case, we would
42 possibly drop IPv6 multicast packets, for the latter IPv4 ones. This is
43 because we are currently assuming that if either an IGMP or MLD querier
44 is present that the other one is present, too.
45
46 This patch makes the behaviour and fix added in
47 "bridge: disable snooping if there is no querier" (b00589af3b04)
48 to also work if there is either just an IGMP or an MLD querier on the
49 link: It refines the deactivation of the snooping to be protocol
50 specific by using separate timers for the snooped IGMP and MLD queries
51 as well as separate timers for our internal IGMP and MLD queriers.
52
53 Signed-off-by: Linus Lüssing <linus.luessing@web.de>
54 Signed-off-by: David S. Miller <davem@davemloft.net>
55
56 commit b00589af3b04736376f24625ab0b394642e89e29
57 Author: Linus Lüssing <linus.luessing@web.de>
58 Date: Thu Aug 1 01:06:20 2013 +0200
59
60 bridge: disable snooping if there is no querier
61
62 If there is no querier on a link then we won't get periodic reports and
63 therefore won't be able to learn about multicast listeners behind ports,
64 potentially leading to lost multicast packets, especially for multicast
65 listeners that joined before the creation of the bridge.
66
67 These lost multicast packets can appear since c5c23260594
68 ("bridge: Add multicast_querier toggle and disable queries by default")
69 in particular.
70
71 With this patch we are flooding multicast packets if our querier is
72 disabled and if we didn't detect any other querier.
73
74 A grace period of the Maximum Response Delay of the querier is added to
75 give multicast responses enough time to arrive and to be learned from
76 before disabling the flooding behaviour again.
77
78 Signed-off-by: Linus Lüssing <linus.luessing@web.de>
79 Signed-off-by: David S. Miller <davem@davemloft.net>
80
81 commit 6b7df111ece130fa979a0c4f58e53674c1e47d3e
82 Author: Cong Wang <amwang@redhat.com>
83 Date: Tue May 21 21:52:56 2013 +0000
84
85 bridge: send query as soon as leave is received
86
87 Continue sending queries when leave is received if the user marks
88 it as a querier.
89
90 Cc: Herbert Xu <herbert@gondor.apana.org.au>
91 Cc: Stephen Hemminger <stephen@networkplumber.org>
92 Cc: "David S. Miller" <davem@davemloft.net>
93 Cc: Adam Baker <linux@baker-net.org.uk>
94 Signed-off-by: Cong Wang <amwang@redhat.com>
95 Acked-by: Herbert Xu <herbert@gondor.apana.org.au>
96 Signed-off-by: David S. Miller <davem@davemloft.net>
97
98 commit 1c8ad5bfa2be5025b0c81e3c2decd0574d453ab1
99 Author: Cong Wang <amwang@redhat.com>
100 Date: Tue May 21 21:52:54 2013 +0000
101
102 bridge: use the bridge IP addr as source addr for querier
103
104 Quote from Adam:
105 "If it is believed that the use of 0.0.0.0
106 as the IP address is what is causing strange behaviour on other devices
107 then is there a good reason that a bridge rather than a router shouldn't
108 be the active querier? If not then using the bridge IP address and
109 having the querier enabled by default may be a reasonable solution
110 (provided that our querier obeys the election rules and shuts up if it
111 sees a query from a lower IP address that isn't 0.0.0.0). Just because a
112 device is the elected querier for IGMP doesn't appear to mean it is
113 required to perform any other routing functions."
114
115 And introduce a new troggle for it, as suggested by Herbert.
116
117 Suggested-by: Adam Baker <linux@baker-net.org.uk>
118 Cc: Herbert Xu <herbert@gondor.apana.org.au>
119 Cc: Stephen Hemminger <stephen@networkplumber.org>
120 Cc: "David S. Miller" <davem@davemloft.net>
121 Cc: Adam Baker <linux@baker-net.org.uk>
122 Signed-off-by: Cong Wang <amwang@redhat.com>
123 Acked-by: Herbert Xu <herbert@gondor.apana.org.au>
124 Signed-off-by: David S. Miller <davem@davemloft.net>
125
126 --- a/net/bridge/br_device.c
127 +++ b/net/bridge/br_device.c
128 @@ -67,7 +67,8 @@ netdev_tx_t br_dev_xmit(struct sk_buff *
129 }
130
131 mdst = br_mdb_get(br, skb, vid);
132 - if (mdst || BR_INPUT_SKB_CB_MROUTERS_ONLY(skb))
133 + if ((mdst || BR_INPUT_SKB_CB_MROUTERS_ONLY(skb)) &&
134 + br_multicast_querier_exists(br, eth_hdr(skb)))
135 br_multicast_deliver(mdst, skb);
136 else
137 br_flood_deliver(br, skb);
138 --- a/net/bridge/br_input.c
139 +++ b/net/bridge/br_input.c
140 @@ -98,7 +98,8 @@ int br_handle_frame_finish(struct sk_buf
141 skb2 = skb;
142 else if (is_multicast_ether_addr(dest)) {
143 mdst = br_mdb_get(br, skb, vid);
144 - if (mdst || BR_INPUT_SKB_CB_MROUTERS_ONLY(skb)) {
145 + if ((mdst || BR_INPUT_SKB_CB_MROUTERS_ONLY(skb)) &&
146 + br_multicast_querier_exists(br, eth_hdr(skb))) {
147 if ((mdst && mdst->mglist) ||
148 br_multicast_is_router(br))
149 skb2 = skb;
150 --- a/net/bridge/br_multicast.c
151 +++ b/net/bridge/br_multicast.c
152 @@ -23,16 +23,19 @@
153 #include <linux/skbuff.h>
154 #include <linux/slab.h>
155 #include <linux/timer.h>
156 +#include <linux/inetdevice.h>
157 #include <net/ip.h>
158 #if IS_ENABLED(CONFIG_IPV6)
159 #include <net/ipv6.h>
160 #include <net/mld.h>
161 #include <net/ip6_checksum.h>
162 +#include <net/addrconf.h>
163 #endif
164
165 #include "br_private.h"
166
167 -static void br_multicast_start_querier(struct net_bridge *br);
168 +static void br_multicast_start_querier(struct net_bridge *br,
169 + struct bridge_mcast_query *query);
170 unsigned int br_mdb_rehash_seq;
171
172 static inline int br_ip_equal(const struct br_ip *a, const struct br_ip *b)
173 @@ -381,7 +384,8 @@ static struct sk_buff *br_ip4_multicast_
174 iph->frag_off = htons(IP_DF);
175 iph->ttl = 1;
176 iph->protocol = IPPROTO_IGMP;
177 - iph->saddr = 0;
178 + iph->saddr = br->multicast_query_use_ifaddr ?
179 + inet_select_addr(br->dev, 0, RT_SCOPE_LINK) : 0;
180 iph->daddr = htonl(INADDR_ALLHOSTS_GROUP);
181 ((u8 *)&iph[1])[0] = IPOPT_RA;
182 ((u8 *)&iph[1])[1] = 4;
183 @@ -724,7 +728,7 @@ static int br_ip6_multicast_add_group(st
184 {
185 struct br_ip br_group;
186
187 - if (!ipv6_is_transient_multicast(group))
188 + if (ipv6_addr_is_ll_all_nodes(group))
189 return 0;
190
191 br_group.u.ip6 = *group;
192 @@ -756,20 +760,35 @@ static void br_multicast_local_router_ex
193 {
194 }
195
196 -static void br_multicast_querier_expired(unsigned long data)
197 +static void br_multicast_querier_expired(struct net_bridge *br,
198 + struct bridge_mcast_query *query)
199 {
200 - struct net_bridge *br = (void *)data;
201 -
202 spin_lock(&br->multicast_lock);
203 if (!netif_running(br->dev) || br->multicast_disabled)
204 goto out;
205
206 - br_multicast_start_querier(br);
207 + br_multicast_start_querier(br, query);
208
209 out:
210 spin_unlock(&br->multicast_lock);
211 }
212
213 +static void br_ip4_multicast_querier_expired(unsigned long data)
214 +{
215 + struct net_bridge *br = (void *)data;
216 +
217 + br_multicast_querier_expired(br, &br->ip4_query);
218 +}
219 +
220 +#if IS_ENABLED(CONFIG_IPV6)
221 +static void br_ip6_multicast_querier_expired(unsigned long data)
222 +{
223 + struct net_bridge *br = (void *)data;
224 +
225 + br_multicast_querier_expired(br, &br->ip6_query);
226 +}
227 +#endif
228 +
229 static void __br_multicast_send_query(struct net_bridge *br,
230 struct net_bridge_port *port,
231 struct br_ip *ip)
232 @@ -790,37 +809,45 @@ static void __br_multicast_send_query(st
233 }
234
235 static void br_multicast_send_query(struct net_bridge *br,
236 - struct net_bridge_port *port, u32 sent)
237 + struct net_bridge_port *port,
238 + struct bridge_mcast_query *query)
239 {
240 unsigned long time;
241 struct br_ip br_group;
242 + struct bridge_mcast_querier *querier = NULL;
243
244 if (!netif_running(br->dev) || br->multicast_disabled ||
245 - !br->multicast_querier ||
246 - timer_pending(&br->multicast_querier_timer))
247 + !br->multicast_querier)
248 return;
249
250 memset(&br_group.u, 0, sizeof(br_group.u));
251
252 - br_group.proto = htons(ETH_P_IP);
253 - __br_multicast_send_query(br, port, &br_group);
254 -
255 + if (port ? (query == &port->ip4_query) :
256 + (query == &br->ip4_query)) {
257 + querier = &br->ip4_querier;
258 + br_group.proto = htons(ETH_P_IP);
259 #if IS_ENABLED(CONFIG_IPV6)
260 - br_group.proto = htons(ETH_P_IPV6);
261 - __br_multicast_send_query(br, port, &br_group);
262 + } else {
263 + querier = &br->ip6_querier;
264 + br_group.proto = htons(ETH_P_IPV6);
265 #endif
266 + }
267 +
268 + if (!querier || timer_pending(&querier->timer))
269 + return;
270 +
271 + __br_multicast_send_query(br, port, &br_group);
272
273 time = jiffies;
274 - time += sent < br->multicast_startup_query_count ?
275 + time += query->startup_sent < br->multicast_startup_query_count ?
276 br->multicast_startup_query_interval :
277 br->multicast_query_interval;
278 - mod_timer(port ? &port->multicast_query_timer :
279 - &br->multicast_query_timer, time);
280 + mod_timer(&query->timer, time);
281 }
282
283 -static void br_multicast_port_query_expired(unsigned long data)
284 +static void br_multicast_port_query_expired(struct net_bridge_port *port,
285 + struct bridge_mcast_query *query)
286 {
287 - struct net_bridge_port *port = (void *)data;
288 struct net_bridge *br = port->br;
289
290 spin_lock(&br->multicast_lock);
291 @@ -828,25 +855,43 @@ static void br_multicast_port_query_expi
292 port->state == BR_STATE_BLOCKING)
293 goto out;
294
295 - if (port->multicast_startup_queries_sent <
296 - br->multicast_startup_query_count)
297 - port->multicast_startup_queries_sent++;
298 + if (query->startup_sent < br->multicast_startup_query_count)
299 + query->startup_sent++;
300
301 - br_multicast_send_query(port->br, port,
302 - port->multicast_startup_queries_sent);
303 + br_multicast_send_query(port->br, port, query);
304
305 out:
306 spin_unlock(&br->multicast_lock);
307 }
308
309 +static void br_ip4_multicast_port_query_expired(unsigned long data)
310 +{
311 + struct net_bridge_port *port = (void *)data;
312 +
313 + br_multicast_port_query_expired(port, &port->ip4_query);
314 +}
315 +
316 +#if IS_ENABLED(CONFIG_IPV6)
317 +static void br_ip6_multicast_port_query_expired(unsigned long data)
318 +{
319 + struct net_bridge_port *port = (void *)data;
320 +
321 + br_multicast_port_query_expired(port, &port->ip6_query);
322 +}
323 +#endif
324 +
325 void br_multicast_add_port(struct net_bridge_port *port)
326 {
327 port->multicast_router = 1;
328
329 setup_timer(&port->multicast_router_timer, br_multicast_router_expired,
330 (unsigned long)port);
331 - setup_timer(&port->multicast_query_timer,
332 - br_multicast_port_query_expired, (unsigned long)port);
333 + setup_timer(&port->ip4_query.timer, br_ip4_multicast_port_query_expired,
334 + (unsigned long)port);
335 +#if IS_ENABLED(CONFIG_IPV6)
336 + setup_timer(&port->ip6_query.timer, br_ip6_multicast_port_query_expired,
337 + (unsigned long)port);
338 +#endif
339 }
340
341 void br_multicast_del_port(struct net_bridge_port *port)
342 @@ -854,13 +899,13 @@ void br_multicast_del_port(struct net_br
343 del_timer_sync(&port->multicast_router_timer);
344 }
345
346 -static void __br_multicast_enable_port(struct net_bridge_port *port)
347 +static void br_multicast_enable(struct bridge_mcast_query *query)
348 {
349 - port->multicast_startup_queries_sent = 0;
350 + query->startup_sent = 0;
351
352 - if (try_to_del_timer_sync(&port->multicast_query_timer) >= 0 ||
353 - del_timer(&port->multicast_query_timer))
354 - mod_timer(&port->multicast_query_timer, jiffies);
355 + if (try_to_del_timer_sync(&query->timer) >= 0 ||
356 + del_timer(&query->timer))
357 + mod_timer(&query->timer, jiffies);
358 }
359
360 void br_multicast_enable_port(struct net_bridge_port *port)
361 @@ -871,7 +916,10 @@ void br_multicast_enable_port(struct net
362 if (br->multicast_disabled || !netif_running(br->dev))
363 goto out;
364
365 - __br_multicast_enable_port(port);
366 + br_multicast_enable(&port->ip4_query);
367 +#if IS_ENABLED(CONFIG_IPV6)
368 + br_multicast_enable(&port->ip6_query);
369 +#endif
370
371 out:
372 spin_unlock(&br->multicast_lock);
373 @@ -890,7 +938,10 @@ void br_multicast_disable_port(struct ne
374 if (!hlist_unhashed(&port->rlist))
375 hlist_del_init_rcu(&port->rlist);
376 del_timer(&port->multicast_router_timer);
377 - del_timer(&port->multicast_query_timer);
378 + del_timer(&port->ip4_query.timer);
379 +#if IS_ENABLED(CONFIG_IPV6)
380 + del_timer(&port->ip6_query.timer);
381 +#endif
382 spin_unlock(&br->multicast_lock);
383 }
384
385 @@ -1015,6 +1066,17 @@ static int br_ip6_multicast_mld2_report(
386 }
387 #endif
388
389 +static void
390 +br_multicast_update_querier_timer(struct net_bridge *br,
391 + struct bridge_mcast_querier *querier,
392 + unsigned long max_delay)
393 +{
394 + if (!timer_pending(&querier->timer))
395 + querier->delay_time = jiffies + max_delay;
396 +
397 + mod_timer(&querier->timer, jiffies + br->multicast_querier_interval);
398 +}
399 +
400 /*
401 * Add port to rotuer_list
402 * list is maintained ordered by pointer value
403 @@ -1065,12 +1127,13 @@ timer:
404
405 static void br_multicast_query_received(struct net_bridge *br,
406 struct net_bridge_port *port,
407 - int saddr)
408 + struct bridge_mcast_querier *querier,
409 + int saddr,
410 + unsigned long max_delay)
411 {
412 if (saddr)
413 - mod_timer(&br->multicast_querier_timer,
414 - jiffies + br->multicast_querier_interval);
415 - else if (timer_pending(&br->multicast_querier_timer))
416 + br_multicast_update_querier_timer(br, querier, max_delay);
417 + else if (timer_pending(&querier->timer))
418 return;
419
420 br_multicast_mark_router(br, port);
421 @@ -1097,8 +1160,6 @@ static int br_ip4_multicast_query(struct
422 (port && port->state == BR_STATE_DISABLED))
423 goto out;
424
425 - br_multicast_query_received(br, port, !!iph->saddr);
426 -
427 group = ih->group;
428
429 if (skb->len == sizeof(*ih)) {
430 @@ -1122,6 +1183,9 @@ static int br_ip4_multicast_query(struct
431 IGMPV3_MRC(ih3->code) * (HZ / IGMP_TIMER_SCALE) : 1;
432 }
433
434 + br_multicast_query_received(br, port, &br->ip4_querier, !!iph->saddr,
435 + max_delay);
436 +
437 if (!group)
438 goto out;
439
440 @@ -1174,8 +1238,6 @@ static int br_ip6_multicast_query(struct
441 (port && port->state == BR_STATE_DISABLED))
442 goto out;
443
444 - br_multicast_query_received(br, port, !ipv6_addr_any(&ip6h->saddr));
445 -
446 /* RFC2710+RFC3810 (MLDv1+MLDv2) require link-local source addresses */
447 if (!(ipv6_addr_type(&ip6h->saddr) & IPV6_ADDR_LINKLOCAL)) {
448 err = -EINVAL;
449 @@ -1203,6 +1265,9 @@ static int br_ip6_multicast_query(struct
450 max_delay = max(msecs_to_jiffies(MLDV2_MRC(ntohs(mld2q->mld2q_mrc))), 1UL);
451 }
452
453 + br_multicast_query_received(br, port, &br->ip6_querier,
454 + !ipv6_addr_any(&ip6h->saddr), max_delay);
455 +
456 if (!group)
457 goto out;
458
459 @@ -1235,7 +1300,9 @@ out:
460
461 static void br_multicast_leave_group(struct net_bridge *br,
462 struct net_bridge_port *port,
463 - struct br_ip *group)
464 + struct br_ip *group,
465 + struct bridge_mcast_querier *querier,
466 + struct bridge_mcast_query *query)
467 {
468 struct net_bridge_mdb_htable *mdb;
469 struct net_bridge_mdb_entry *mp;
470 @@ -1246,7 +1313,7 @@ static void br_multicast_leave_group(str
471 spin_lock(&br->multicast_lock);
472 if (!netif_running(br->dev) ||
473 (port && port->state == BR_STATE_DISABLED) ||
474 - timer_pending(&br->multicast_querier_timer))
475 + timer_pending(&querier->timer))
476 goto out;
477
478 mdb = mlock_dereference(br->mdb, br);
479 @@ -1254,6 +1321,31 @@ static void br_multicast_leave_group(str
480 if (!mp)
481 goto out;
482
483 + if (br->multicast_querier) {
484 + __br_multicast_send_query(br, port, &mp->addr);
485 +
486 + time = jiffies + br->multicast_last_member_count *
487 + br->multicast_last_member_interval;
488 +
489 + mod_timer(&query->timer, time);
490 +
491 + for (p = mlock_dereference(mp->ports, br);
492 + p != NULL;
493 + p = mlock_dereference(p->next, br)) {
494 + if (p->port != port)
495 + continue;
496 +
497 + if (!hlist_unhashed(&p->mglist) &&
498 + (timer_pending(&p->timer) ?
499 + time_after(p->timer.expires, time) :
500 + try_to_del_timer_sync(&p->timer) >= 0)) {
501 + mod_timer(&p->timer, time);
502 + }
503 +
504 + break;
505 + }
506 + }
507 +
508 if (port && (port->flags & BR_MULTICAST_FAST_LEAVE)) {
509 struct net_bridge_port_group __rcu **pp;
510
511 @@ -1306,7 +1398,6 @@ static void br_multicast_leave_group(str
512
513 break;
514 }
515 -
516 out:
517 spin_unlock(&br->multicast_lock);
518 }
519 @@ -1317,6 +1408,8 @@ static void br_ip4_multicast_leave_group
520 __u16 vid)
521 {
522 struct br_ip br_group;
523 + struct bridge_mcast_query *query = port ? &port->ip4_query :
524 + &br->ip4_query;
525
526 if (ipv4_is_local_multicast(group))
527 return;
528 @@ -1325,7 +1418,7 @@ static void br_ip4_multicast_leave_group
529 br_group.proto = htons(ETH_P_IP);
530 br_group.vid = vid;
531
532 - br_multicast_leave_group(br, port, &br_group);
533 + br_multicast_leave_group(br, port, &br_group, &br->ip4_querier, query);
534 }
535
536 #if IS_ENABLED(CONFIG_IPV6)
537 @@ -1335,15 +1428,18 @@ static void br_ip6_multicast_leave_group
538 __u16 vid)
539 {
540 struct br_ip br_group;
541 + struct bridge_mcast_query *query = port ? &port->ip6_query :
542 + &br->ip6_query;
543
544 - if (!ipv6_is_transient_multicast(group))
545 +
546 + if (ipv6_addr_is_ll_all_nodes(group))
547 return;
548
549 br_group.u.ip6 = *group;
550 br_group.proto = htons(ETH_P_IPV6);
551 br_group.vid = vid;
552
553 - br_multicast_leave_group(br, port, &br_group);
554 + br_multicast_leave_group(br, port, &br_group, &br->ip6_querier, query);
555 }
556 #endif
557
558 @@ -1473,8 +1569,14 @@ static int br_multicast_ipv6_rcv(struct
559 * - MLD has always Router Alert hop-by-hop option
560 * - But we do not support jumbrograms.
561 */
562 - if (ip6h->version != 6 ||
563 - ip6h->nexthdr != IPPROTO_HOPOPTS ||
564 + if (ip6h->version != 6)
565 + return 0;
566 +
567 + /* Prevent flooding this packet if there is no listener present */
568 + if (!ipv6_addr_is_ll_all_nodes(&ip6h->daddr))
569 + BR_INPUT_SKB_CB(skb)->mrouters_only = 1;
570 +
571 + if (ip6h->nexthdr != IPPROTO_HOPOPTS ||
572 ip6h->payload_len == 0)
573 return 0;
574
575 @@ -1605,19 +1707,32 @@ int br_multicast_rcv(struct net_bridge *
576 return 0;
577 }
578
579 -static void br_multicast_query_expired(unsigned long data)
580 +static void br_multicast_query_expired(struct net_bridge *br,
581 + struct bridge_mcast_query *query)
582 +{
583 + spin_lock(&br->multicast_lock);
584 + if (query->startup_sent < br->multicast_startup_query_count)
585 + query->startup_sent++;
586 +
587 + br_multicast_send_query(br, NULL, query);
588 + spin_unlock(&br->multicast_lock);
589 +}
590 +
591 +static void br_ip4_multicast_query_expired(unsigned long data)
592 {
593 struct net_bridge *br = (void *)data;
594
595 - spin_lock(&br->multicast_lock);
596 - if (br->multicast_startup_queries_sent <
597 - br->multicast_startup_query_count)
598 - br->multicast_startup_queries_sent++;
599 + br_multicast_query_expired(br, &br->ip4_query);
600 +}
601
602 - br_multicast_send_query(br, NULL, br->multicast_startup_queries_sent);
603 +#if IS_ENABLED(CONFIG_IPV6)
604 +static void br_ip6_multicast_query_expired(unsigned long data)
605 +{
606 + struct net_bridge *br = (void *)data;
607
608 - spin_unlock(&br->multicast_lock);
609 + br_multicast_query_expired(br, &br->ip6_query);
610 }
611 +#endif
612
613 void br_multicast_init(struct net_bridge *br)
614 {
615 @@ -1626,6 +1741,7 @@ void br_multicast_init(struct net_bridge
616
617 br->multicast_router = 1;
618 br->multicast_querier = 0;
619 + br->multicast_query_use_ifaddr = 0;
620 br->multicast_last_member_count = 2;
621 br->multicast_startup_query_count = 2;
622
623 @@ -1636,23 +1752,43 @@ void br_multicast_init(struct net_bridge
624 br->multicast_querier_interval = 255 * HZ;
625 br->multicast_membership_interval = 260 * HZ;
626
627 + br->ip4_querier.delay_time = 0;
628 +#if IS_ENABLED(CONFIG_IPV6)
629 + br->ip6_querier.delay_time = 0;
630 +#endif
631 +
632 spin_lock_init(&br->multicast_lock);
633 setup_timer(&br->multicast_router_timer,
634 br_multicast_local_router_expired, 0);
635 - setup_timer(&br->multicast_querier_timer,
636 - br_multicast_querier_expired, (unsigned long)br);
637 - setup_timer(&br->multicast_query_timer, br_multicast_query_expired,
638 + setup_timer(&br->ip4_querier.timer, br_ip4_multicast_querier_expired,
639 (unsigned long)br);
640 + setup_timer(&br->ip4_query.timer, br_ip4_multicast_query_expired,
641 + (unsigned long)br);
642 +#if IS_ENABLED(CONFIG_IPV6)
643 + setup_timer(&br->ip6_querier.timer, br_ip6_multicast_querier_expired,
644 + (unsigned long)br);
645 + setup_timer(&br->ip6_query.timer, br_ip6_multicast_query_expired,
646 + (unsigned long)br);
647 +#endif
648 }
649
650 -void br_multicast_open(struct net_bridge *br)
651 +static void __br_multicast_open(struct net_bridge *br,
652 + struct bridge_mcast_query *query)
653 {
654 - br->multicast_startup_queries_sent = 0;
655 + query->startup_sent = 0;
656
657 if (br->multicast_disabled)
658 return;
659
660 - mod_timer(&br->multicast_query_timer, jiffies);
661 + mod_timer(&query->timer, jiffies);
662 +}
663 +
664 +void br_multicast_open(struct net_bridge *br)
665 +{
666 + __br_multicast_open(br, &br->ip4_query);
667 +#if IS_ENABLED(CONFIG_IPV6)
668 + __br_multicast_open(br, &br->ip6_query);
669 +#endif
670 }
671
672 void br_multicast_stop(struct net_bridge *br)
673 @@ -1664,8 +1800,12 @@ void br_multicast_stop(struct net_bridge
674 int i;
675
676 del_timer_sync(&br->multicast_router_timer);
677 - del_timer_sync(&br->multicast_querier_timer);
678 - del_timer_sync(&br->multicast_query_timer);
679 + del_timer_sync(&br->ip4_querier.timer);
680 + del_timer_sync(&br->ip4_query.timer);
681 +#if IS_ENABLED(CONFIG_IPV6)
682 + del_timer_sync(&br->ip6_querier.timer);
683 + del_timer_sync(&br->ip6_query.timer);
684 +#endif
685
686 spin_lock_bh(&br->multicast_lock);
687 mdb = mlock_dereference(br->mdb, br);
688 @@ -1767,18 +1907,24 @@ unlock:
689 return err;
690 }
691
692 -static void br_multicast_start_querier(struct net_bridge *br)
693 +static void br_multicast_start_querier(struct net_bridge *br,
694 + struct bridge_mcast_query *query)
695 {
696 struct net_bridge_port *port;
697
698 - br_multicast_open(br);
699 + __br_multicast_open(br, query);
700
701 list_for_each_entry(port, &br->port_list, list) {
702 if (port->state == BR_STATE_DISABLED ||
703 port->state == BR_STATE_BLOCKING)
704 continue;
705
706 - __br_multicast_enable_port(port);
707 + if (query == &br->ip4_query)
708 + br_multicast_enable(&port->ip4_query);
709 +#if IS_ENABLED(CONFIG_IPV6)
710 + else
711 + br_multicast_enable(&port->ip6_query);
712 +#endif
713 }
714 }
715
716 @@ -1813,7 +1959,10 @@ rollback:
717 goto rollback;
718 }
719
720 - br_multicast_start_querier(br);
721 + br_multicast_start_querier(br, &br->ip4_query);
722 +#if IS_ENABLED(CONFIG_IPV6)
723 + br_multicast_start_querier(br, &br->ip6_query);
724 +#endif
725
726 unlock:
727 spin_unlock_bh(&br->multicast_lock);
728 @@ -1823,6 +1972,8 @@ unlock:
729
730 int br_multicast_set_querier(struct net_bridge *br, unsigned long val)
731 {
732 + unsigned long max_delay;
733 +
734 val = !!val;
735
736 spin_lock_bh(&br->multicast_lock);
737 @@ -1830,8 +1981,22 @@ int br_multicast_set_querier(struct net_
738 goto unlock;
739
740 br->multicast_querier = val;
741 - if (val)
742 - br_multicast_start_querier(br);
743 + if (!val)
744 + goto unlock;
745 +
746 + max_delay = br->multicast_query_response_interval;
747 +
748 + if (!timer_pending(&br->ip4_querier.timer))
749 + br->ip4_querier.delay_time = jiffies + max_delay;
750 +
751 + br_multicast_start_querier(br, &br->ip4_query);
752 +
753 +#if IS_ENABLED(CONFIG_IPV6)
754 + if (!timer_pending(&br->ip6_querier.timer))
755 + br->ip6_querier.delay_time = jiffies + max_delay;
756 +
757 + br_multicast_start_querier(br, &br->ip6_query);
758 +#endif
759
760 unlock:
761 spin_unlock_bh(&br->multicast_lock);
762 --- a/net/bridge/br_private.h
763 +++ b/net/bridge/br_private.h
764 @@ -66,6 +66,20 @@ struct br_ip
765 __u16 vid;
766 };
767
768 +#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
769 +/* our own querier */
770 +struct bridge_mcast_query {
771 + struct timer_list timer;
772 + u32 startup_sent;
773 +};
774 +
775 +/* other querier */
776 +struct bridge_mcast_querier {
777 + struct timer_list timer;
778 + unsigned long delay_time;
779 +};
780 +#endif
781 +
782 struct net_port_vlans {
783 u16 port_idx;
784 u16 pvid;
785 @@ -159,10 +173,12 @@ struct net_bridge_port
786 #define BR_ADMIN_COST 0x00000010
787
788 #ifdef CONFIG_BRIDGE_IGMP_SNOOPING
789 - u32 multicast_startup_queries_sent;
790 + struct bridge_mcast_query ip4_query;
791 +#if IS_ENABLED(CONFIG_IPV6)
792 + struct bridge_mcast_query ip6_query;
793 +#endif /* IS_ENABLED(CONFIG_IPV6) */
794 unsigned char multicast_router;
795 struct timer_list multicast_router_timer;
796 - struct timer_list multicast_query_timer;
797 struct hlist_head mglist;
798 struct hlist_node rlist;
799 #endif
800 @@ -246,12 +262,12 @@ struct net_bridge
801
802 u8 multicast_disabled:1;
803 u8 multicast_querier:1;
804 + u8 multicast_query_use_ifaddr:1;
805
806 u32 hash_elasticity;
807 u32 hash_max;
808
809 u32 multicast_last_member_count;
810 - u32 multicast_startup_queries_sent;
811 u32 multicast_startup_query_count;
812
813 unsigned long multicast_last_member_interval;
814 @@ -266,8 +282,12 @@ struct net_bridge
815 struct hlist_head router_list;
816
817 struct timer_list multicast_router_timer;
818 - struct timer_list multicast_querier_timer;
819 - struct timer_list multicast_query_timer;
820 + struct bridge_mcast_querier ip4_querier;
821 + struct bridge_mcast_query ip4_query;
822 +#if IS_ENABLED(CONFIG_IPV6)
823 + struct bridge_mcast_querier ip6_querier;
824 + struct bridge_mcast_query ip6_query;
825 +#endif /* IS_ENABLED(CONFIG_IPV6) */
826 #endif
827
828 struct timer_list hello_timer;
829 @@ -477,22 +497,35 @@ extern void br_mdb_notify(struct net_dev
830 #define mlock_dereference(X, br) \
831 rcu_dereference_protected(X, lockdep_is_held(&br->multicast_lock))
832
833 -#if IS_ENABLED(CONFIG_IPV6)
834 -#include <net/addrconf.h>
835 -static inline int ipv6_is_transient_multicast(const struct in6_addr *addr)
836 -{
837 - if (ipv6_addr_is_multicast(addr) && IPV6_ADDR_MC_FLAG_TRANSIENT(addr))
838 - return 1;
839 - return 0;
840 -}
841 -#endif
842 -
843 static inline bool br_multicast_is_router(struct net_bridge *br)
844 {
845 return br->multicast_router == 2 ||
846 (br->multicast_router == 1 &&
847 timer_pending(&br->multicast_router_timer));
848 }
849 +
850 +static inline bool
851 +__br_multicast_querier_exists(struct net_bridge *br,
852 + struct bridge_mcast_querier *querier)
853 +{
854 + return time_is_before_jiffies(querier->delay_time) &&
855 + (br->multicast_querier || timer_pending(&querier->timer));
856 +}
857 +
858 +static inline bool br_multicast_querier_exists(struct net_bridge *br,
859 + struct ethhdr *eth)
860 +{
861 + switch (eth->h_proto) {
862 + case (htons(ETH_P_IP)):
863 + return __br_multicast_querier_exists(br, &br->ip4_querier);
864 +#if IS_ENABLED(CONFIG_IPV6)
865 + case (htons(ETH_P_IPV6)):
866 + return __br_multicast_querier_exists(br, &br->ip6_querier);
867 +#endif
868 + default:
869 + return false;
870 + }
871 +}
872 #else
873 static inline int br_multicast_rcv(struct net_bridge *br,
874 struct net_bridge_port *port,
875 @@ -549,6 +582,11 @@ static inline bool br_multicast_is_route
876 {
877 return 0;
878 }
879 +static inline bool br_multicast_querier_exists(struct net_bridge *br,
880 + struct ethhdr *eth)
881 +{
882 + return false;
883 +}
884 static inline void br_mdb_init(void)
885 {
886 }
887 --- a/net/bridge/br_sysfs_br.c
888 +++ b/net/bridge/br_sysfs_br.c
889 @@ -375,6 +375,31 @@ static ssize_t store_multicast_snooping(
890 static DEVICE_ATTR(multicast_snooping, S_IRUGO | S_IWUSR,
891 show_multicast_snooping, store_multicast_snooping);
892
893 +static ssize_t show_multicast_query_use_ifaddr(struct device *d,
894 + struct device_attribute *attr,
895 + char *buf)
896 +{
897 + struct net_bridge *br = to_bridge(d);
898 + return sprintf(buf, "%d\n", br->multicast_query_use_ifaddr);
899 +}
900 +
901 +static int set_query_use_ifaddr(struct net_bridge *br, unsigned long val)
902 +{
903 + br->multicast_query_use_ifaddr = !!val;
904 + return 0;
905 +}
906 +
907 +static ssize_t
908 +store_multicast_query_use_ifaddr(struct device *d,
909 + struct device_attribute *attr,
910 + const char *buf, size_t len)
911 +{
912 + return store_bridge_parm(d, buf, len, set_query_use_ifaddr);
913 +}
914 +static DEVICE_ATTR(multicast_query_use_ifaddr, S_IRUGO | S_IWUSR,
915 + show_multicast_query_use_ifaddr,
916 + store_multicast_query_use_ifaddr);
917 +
918 static ssize_t show_multicast_querier(struct device *d,
919 struct device_attribute *attr,
920 char *buf)
921 @@ -734,6 +759,7 @@ static struct attribute *bridge_attrs[]
922 &dev_attr_multicast_router.attr,
923 &dev_attr_multicast_snooping.attr,
924 &dev_attr_multicast_querier.attr,
925 + &dev_attr_multicast_query_use_ifaddr.attr,
926 &dev_attr_hash_elasticity.attr,
927 &dev_attr_hash_max.attr,
928 &dev_attr_multicast_last_member_count.attr,
929 --- a/net/bridge/br_mdb.c
930 +++ b/net/bridge/br_mdb.c
931 @@ -9,6 +9,7 @@
932 #include <net/netlink.h>
933 #if IS_ENABLED(CONFIG_IPV6)
934 #include <net/ipv6.h>
935 +#include <net/addrconf.h>
936 #endif
937
938 #include "br_private.h"
939 @@ -253,7 +254,7 @@ static bool is_valid_mdb_entry(struct br
940 return false;
941 #if IS_ENABLED(CONFIG_IPV6)
942 } else if (entry->addr.proto == htons(ETH_P_IPV6)) {
943 - if (!ipv6_is_transient_multicast(&entry->addr.u.ip6))
944 + if (ipv6_addr_is_ll_all_nodes(&entry->addr.u.ip6))
945 return false;
946 #endif
947 } else
948 @@ -414,16 +415,20 @@ static int __br_mdb_del(struct net_bridg
949 if (!netif_running(br->dev) || br->multicast_disabled)
950 return -EINVAL;
951
952 - if (timer_pending(&br->multicast_querier_timer))
953 - return -EBUSY;
954 -
955 ip.proto = entry->addr.proto;
956 - if (ip.proto == htons(ETH_P_IP))
957 + if (ip.proto == htons(ETH_P_IP)) {
958 + if (timer_pending(&br->ip4_querier.timer))
959 + return -EBUSY;
960 +
961 ip.u.ip4 = entry->addr.u.ip4;
962 #if IS_ENABLED(CONFIG_IPV6)
963 - else
964 + } else {
965 + if (timer_pending(&br->ip6_querier.timer))
966 + return -EBUSY;
967 +
968 ip.u.ip6 = entry->addr.u.ip6;
969 #endif
970 + }
971
972 spin_lock_bh(&br->multicast_lock);
973 mdb = mlock_dereference(br->mdb, br);