aboutsummaryrefslogtreecommitdiff
path: root/net/bridge/br_multicast.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-02-23 16:02:00 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2011-02-23 16:02:00 -0800
commitef3242859fae47e728b50b7ce3d17b201a71779a (patch)
tree7857320b5209cafc231b329b9dab67ddb53f8128 /net/bridge/br_multicast.c
parentb5f7376eb30538d03dd27f6a59b5b2d28587967c (diff)
parent518d020a18716024187ee0b834c8f5bfebd59398 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6: (33 commits) Added support for usb ethernet (0x0fe6, 0x9700) r8169: fix RTL8168DP power off issue. r8169: correct settings of rtl8102e. r8169: fix incorrect args to oob notify. DM9000B: Fix PHY power for network down/up DM9000B: Fix reg_save after spin_lock in dm9000_timeout net_sched: long word align struct qdisc_skb_cb data sfc: lower stack usage in efx_ethtool_self_test bridge: Use IPv6 link-local address for multicast listener queries bridge: Fix MLD queries' ethernet source address bridge: Allow mcast snooping for transient link local addresses too ipv6: Add IPv6 multicast address flag defines bridge: Add missing ntohs()s for MLDv2 report parsing bridge: Fix IPv6 multicast snooping by correcting offset in MLDv2 report bridge: Fix IPv6 multicast snooping by storing correct protocol type p54pci: update receive dma buffers before and after processing fix cfg80211_wext_siwfreq lock ordering... rt2x00: Fix WPA TKIP Michael MIC failures. ath5k: Fix fast channel switching tcp: undo_retrans counter fixes ...
Diffstat (limited to 'net/bridge/br_multicast.c')
-rw-r--r--net/bridge/br_multicast.c23
1 files changed, 12 insertions, 11 deletions
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
index 09d5c098792..030a002ff8e 100644
--- a/net/bridge/br_multicast.c
+++ b/net/bridge/br_multicast.c
@@ -37,10 +37,9 @@
rcu_dereference_protected(X, lockdep_is_held(&br->multicast_lock))
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-static inline int ipv6_is_local_multicast(const struct in6_addr *addr)
+static inline int ipv6_is_transient_multicast(const struct in6_addr *addr)
{
- if (ipv6_addr_is_multicast(addr) &&
- IPV6_ADDR_MC_SCOPE(addr) <= IPV6_ADDR_SCOPE_LINKLOCAL)
+ if (ipv6_addr_is_multicast(addr) && IPV6_ADDR_MC_FLAG_TRANSIENT(addr))
return 1;
return 0;
}
@@ -435,7 +434,6 @@ static struct sk_buff *br_ip6_multicast_alloc_query(struct net_bridge *br,
eth = eth_hdr(skb);
memcpy(eth->h_source, br->dev->dev_addr, 6);
- ipv6_eth_mc_map(group, eth->h_dest);
eth->h_proto = htons(ETH_P_IPV6);
skb_put(skb, sizeof(*eth));
@@ -447,8 +445,10 @@ static struct sk_buff *br_ip6_multicast_alloc_query(struct net_bridge *br,
ip6h->payload_len = htons(8 + sizeof(*mldq));
ip6h->nexthdr = IPPROTO_HOPOPTS;
ip6h->hop_limit = 1;
- ipv6_addr_set(&ip6h->saddr, 0, 0, 0, 0);
+ ipv6_dev_get_saddr(dev_net(br->dev), br->dev, &ip6h->daddr, 0,
+ &ip6h->saddr);
ipv6_addr_set(&ip6h->daddr, htonl(0xff020000), 0, 0, htonl(1));
+ ipv6_eth_mc_map(&ip6h->daddr, eth->h_dest);
hopopt = (u8 *)(ip6h + 1);
hopopt[0] = IPPROTO_ICMPV6; /* next hdr */
@@ -780,11 +780,11 @@ static int br_ip6_multicast_add_group(struct net_bridge *br,
{
struct br_ip br_group;
- if (ipv6_is_local_multicast(group))
+ if (!ipv6_is_transient_multicast(group))
return 0;
ipv6_addr_copy(&br_group.u.ip6, group);
- br_group.proto = htons(ETH_P_IP);
+ br_group.proto = htons(ETH_P_IPV6);
return br_multicast_add_group(br, port, &br_group);
}
@@ -1013,18 +1013,19 @@ static int br_ip6_multicast_mld2_report(struct net_bridge *br,
nsrcs = skb_header_pointer(skb,
len + offsetof(struct mld2_grec,
- grec_mca),
+ grec_nsrcs),
sizeof(_nsrcs), &_nsrcs);
if (!nsrcs)
return -EINVAL;
if (!pskb_may_pull(skb,
len + sizeof(*grec) +
- sizeof(struct in6_addr) * (*nsrcs)))
+ sizeof(struct in6_addr) * ntohs(*nsrcs)))
return -EINVAL;
grec = (struct mld2_grec *)(skb->data + len);
- len += sizeof(*grec) + sizeof(struct in6_addr) * (*nsrcs);
+ len += sizeof(*grec) +
+ sizeof(struct in6_addr) * ntohs(*nsrcs);
/* We treat these as MLDv1 reports for now. */
switch (grec->grec_type) {
@@ -1340,7 +1341,7 @@ static void br_ip6_multicast_leave_group(struct net_bridge *br,
{
struct br_ip br_group;
- if (ipv6_is_local_multicast(group))
+ if (!ipv6_is_transient_multicast(group))
return;
ipv6_addr_copy(&br_group.u.ip6, group);