aboutsummaryrefslogtreecommitdiffstats
path: root/net/bridge/br_multicast.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/bridge/br_multicast.c')
-rw-r--r--net/bridge/br_multicast.c42
1 files changed, 21 insertions, 21 deletions
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
index f701a21acb34..030a002ff8ee 100644
--- a/net/bridge/br_multicast.c
+++ b/net/bridge/br_multicast.c
@@ -37,10 +37,9 @@
37 rcu_dereference_protected(X, lockdep_is_held(&br->multicast_lock)) 37 rcu_dereference_protected(X, lockdep_is_held(&br->multicast_lock))
38 38
39#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 39#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
40static inline int ipv6_is_local_multicast(const struct in6_addr *addr) 40static inline int ipv6_is_transient_multicast(const struct in6_addr *addr)
41{ 41{
42 if (ipv6_addr_is_multicast(addr) && 42 if (ipv6_addr_is_multicast(addr) && IPV6_ADDR_MC_FLAG_TRANSIENT(addr))
43 IPV6_ADDR_MC_SCOPE(addr) <= IPV6_ADDR_SCOPE_LINKLOCAL)
44 return 1; 43 return 1;
45 return 0; 44 return 0;
46} 45}
@@ -232,8 +231,7 @@ static void br_multicast_group_expired(unsigned long data)
232 if (!netif_running(br->dev) || timer_pending(&mp->timer)) 231 if (!netif_running(br->dev) || timer_pending(&mp->timer))
233 goto out; 232 goto out;
234 233
235 if (!hlist_unhashed(&mp->mglist)) 234 mp->mglist = false;
236 hlist_del_init(&mp->mglist);
237 235
238 if (mp->ports) 236 if (mp->ports)
239 goto out; 237 goto out;
@@ -276,7 +274,7 @@ static void br_multicast_del_pg(struct net_bridge *br,
276 del_timer(&p->query_timer); 274 del_timer(&p->query_timer);
277 call_rcu_bh(&p->rcu, br_multicast_free_pg); 275 call_rcu_bh(&p->rcu, br_multicast_free_pg);
278 276
279 if (!mp->ports && hlist_unhashed(&mp->mglist) && 277 if (!mp->ports && !mp->mglist &&
280 netif_running(br->dev)) 278 netif_running(br->dev))
281 mod_timer(&mp->timer, jiffies); 279 mod_timer(&mp->timer, jiffies);
282 280
@@ -436,7 +434,6 @@ static struct sk_buff *br_ip6_multicast_alloc_query(struct net_bridge *br,
436 eth = eth_hdr(skb); 434 eth = eth_hdr(skb);
437 435
438 memcpy(eth->h_source, br->dev->dev_addr, 6); 436 memcpy(eth->h_source, br->dev->dev_addr, 6);
439 ipv6_eth_mc_map(group, eth->h_dest);
440 eth->h_proto = htons(ETH_P_IPV6); 437 eth->h_proto = htons(ETH_P_IPV6);
441 skb_put(skb, sizeof(*eth)); 438 skb_put(skb, sizeof(*eth));
442 439
@@ -448,8 +445,10 @@ static struct sk_buff *br_ip6_multicast_alloc_query(struct net_bridge *br,
448 ip6h->payload_len = htons(8 + sizeof(*mldq)); 445 ip6h->payload_len = htons(8 + sizeof(*mldq));
449 ip6h->nexthdr = IPPROTO_HOPOPTS; 446 ip6h->nexthdr = IPPROTO_HOPOPTS;
450 ip6h->hop_limit = 1; 447 ip6h->hop_limit = 1;
451 ipv6_addr_set(&ip6h->saddr, 0, 0, 0, 0); 448 ipv6_dev_get_saddr(dev_net(br->dev), br->dev, &ip6h->daddr, 0,
449 &ip6h->saddr);
452 ipv6_addr_set(&ip6h->daddr, htonl(0xff020000), 0, 0, htonl(1)); 450 ipv6_addr_set(&ip6h->daddr, htonl(0xff020000), 0, 0, htonl(1));
451 ipv6_eth_mc_map(&ip6h->daddr, eth->h_dest);
453 452
454 hopopt = (u8 *)(ip6h + 1); 453 hopopt = (u8 *)(ip6h + 1);
455 hopopt[0] = IPPROTO_ICMPV6; /* next hdr */ 454 hopopt[0] = IPPROTO_ICMPV6; /* next hdr */
@@ -528,7 +527,7 @@ static void br_multicast_group_query_expired(unsigned long data)
528 struct net_bridge *br = mp->br; 527 struct net_bridge *br = mp->br;
529 528
530 spin_lock(&br->multicast_lock); 529 spin_lock(&br->multicast_lock);
531 if (!netif_running(br->dev) || hlist_unhashed(&mp->mglist) || 530 if (!netif_running(br->dev) || !mp->mglist ||
532 mp->queries_sent >= br->multicast_last_member_count) 531 mp->queries_sent >= br->multicast_last_member_count)
533 goto out; 532 goto out;
534 533
@@ -719,7 +718,7 @@ static int br_multicast_add_group(struct net_bridge *br,
719 goto err; 718 goto err;
720 719
721 if (!port) { 720 if (!port) {
722 hlist_add_head(&mp->mglist, &br->mglist); 721 mp->mglist = true;
723 mod_timer(&mp->timer, now + br->multicast_membership_interval); 722 mod_timer(&mp->timer, now + br->multicast_membership_interval);
724 goto out; 723 goto out;
725 } 724 }
@@ -781,11 +780,11 @@ static int br_ip6_multicast_add_group(struct net_bridge *br,
781{ 780{
782 struct br_ip br_group; 781 struct br_ip br_group;
783 782
784 if (ipv6_is_local_multicast(group)) 783 if (!ipv6_is_transient_multicast(group))
785 return 0; 784 return 0;
786 785
787 ipv6_addr_copy(&br_group.u.ip6, group); 786 ipv6_addr_copy(&br_group.u.ip6, group);
788 br_group.proto = htons(ETH_P_IP); 787 br_group.proto = htons(ETH_P_IPV6);
789 788
790 return br_multicast_add_group(br, port, &br_group); 789 return br_multicast_add_group(br, port, &br_group);
791} 790}
@@ -1014,18 +1013,19 @@ static int br_ip6_multicast_mld2_report(struct net_bridge *br,
1014 1013
1015 nsrcs = skb_header_pointer(skb, 1014 nsrcs = skb_header_pointer(skb,
1016 len + offsetof(struct mld2_grec, 1015 len + offsetof(struct mld2_grec,
1017 grec_mca), 1016 grec_nsrcs),
1018 sizeof(_nsrcs), &_nsrcs); 1017 sizeof(_nsrcs), &_nsrcs);
1019 if (!nsrcs) 1018 if (!nsrcs)
1020 return -EINVAL; 1019 return -EINVAL;
1021 1020
1022 if (!pskb_may_pull(skb, 1021 if (!pskb_may_pull(skb,
1023 len + sizeof(*grec) + 1022 len + sizeof(*grec) +
1024 sizeof(struct in6_addr) * (*nsrcs))) 1023 sizeof(struct in6_addr) * ntohs(*nsrcs)))
1025 return -EINVAL; 1024 return -EINVAL;
1026 1025
1027 grec = (struct mld2_grec *)(skb->data + len); 1026 grec = (struct mld2_grec *)(skb->data + len);
1028 len += sizeof(*grec) + sizeof(struct in6_addr) * (*nsrcs); 1027 len += sizeof(*grec) +
1028 sizeof(struct in6_addr) * ntohs(*nsrcs);
1029 1029
1030 /* We treat these as MLDv1 reports for now. */ 1030 /* We treat these as MLDv1 reports for now. */
1031 switch (grec->grec_type) { 1031 switch (grec->grec_type) {
@@ -1165,7 +1165,7 @@ static int br_ip4_multicast_query(struct net_bridge *br,
1165 1165
1166 max_delay *= br->multicast_last_member_count; 1166 max_delay *= br->multicast_last_member_count;
1167 1167
1168 if (!hlist_unhashed(&mp->mglist) && 1168 if (mp->mglist &&
1169 (timer_pending(&mp->timer) ? 1169 (timer_pending(&mp->timer) ?
1170 time_after(mp->timer.expires, now + max_delay) : 1170 time_after(mp->timer.expires, now + max_delay) :
1171 try_to_del_timer_sync(&mp->timer) >= 0)) 1171 try_to_del_timer_sync(&mp->timer) >= 0))
@@ -1177,7 +1177,7 @@ static int br_ip4_multicast_query(struct net_bridge *br,
1177 if (timer_pending(&p->timer) ? 1177 if (timer_pending(&p->timer) ?
1178 time_after(p->timer.expires, now + max_delay) : 1178 time_after(p->timer.expires, now + max_delay) :
1179 try_to_del_timer_sync(&p->timer) >= 0) 1179 try_to_del_timer_sync(&p->timer) >= 0)
1180 mod_timer(&mp->timer, now + max_delay); 1180 mod_timer(&p->timer, now + max_delay);
1181 } 1181 }
1182 1182
1183out: 1183out:
@@ -1236,7 +1236,7 @@ static int br_ip6_multicast_query(struct net_bridge *br,
1236 goto out; 1236 goto out;
1237 1237
1238 max_delay *= br->multicast_last_member_count; 1238 max_delay *= br->multicast_last_member_count;
1239 if (!hlist_unhashed(&mp->mglist) && 1239 if (mp->mglist &&
1240 (timer_pending(&mp->timer) ? 1240 (timer_pending(&mp->timer) ?
1241 time_after(mp->timer.expires, now + max_delay) : 1241 time_after(mp->timer.expires, now + max_delay) :
1242 try_to_del_timer_sync(&mp->timer) >= 0)) 1242 try_to_del_timer_sync(&mp->timer) >= 0))
@@ -1248,7 +1248,7 @@ static int br_ip6_multicast_query(struct net_bridge *br,
1248 if (timer_pending(&p->timer) ? 1248 if (timer_pending(&p->timer) ?
1249 time_after(p->timer.expires, now + max_delay) : 1249 time_after(p->timer.expires, now + max_delay) :
1250 try_to_del_timer_sync(&p->timer) >= 0) 1250 try_to_del_timer_sync(&p->timer) >= 0)
1251 mod_timer(&mp->timer, now + max_delay); 1251 mod_timer(&p->timer, now + max_delay);
1252 } 1252 }
1253 1253
1254out: 1254out:
@@ -1283,7 +1283,7 @@ static void br_multicast_leave_group(struct net_bridge *br,
1283 br->multicast_last_member_interval; 1283 br->multicast_last_member_interval;
1284 1284
1285 if (!port) { 1285 if (!port) {
1286 if (!hlist_unhashed(&mp->mglist) && 1286 if (mp->mglist &&
1287 (timer_pending(&mp->timer) ? 1287 (timer_pending(&mp->timer) ?
1288 time_after(mp->timer.expires, time) : 1288 time_after(mp->timer.expires, time) :
1289 try_to_del_timer_sync(&mp->timer) >= 0)) { 1289 try_to_del_timer_sync(&mp->timer) >= 0)) {
@@ -1341,7 +1341,7 @@ static void br_ip6_multicast_leave_group(struct net_bridge *br,
1341{ 1341{
1342 struct br_ip br_group; 1342 struct br_ip br_group;
1343 1343
1344 if (ipv6_is_local_multicast(group)) 1344 if (!ipv6_is_transient_multicast(group))
1345 return; 1345 return;
1346 1346
1347 ipv6_addr_copy(&br_group.u.ip6, group); 1347 ipv6_addr_copy(&br_group.u.ip6, group);