diff options
Diffstat (limited to 'net/bridge/br_multicast.c')
-rw-r--r-- | net/bridge/br_multicast.c | 19 |
1 files changed, 11 insertions, 8 deletions
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index 2559fb539836..fd96a8dc97f4 100644 --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c | |||
@@ -38,7 +38,7 @@ static struct net_bridge_mdb_entry *__br_mdb_ip_get( | |||
38 | struct net_bridge_mdb_entry *mp; | 38 | struct net_bridge_mdb_entry *mp; |
39 | struct hlist_node *p; | 39 | struct hlist_node *p; |
40 | 40 | ||
41 | hlist_for_each_entry(mp, p, &mdb->mhash[hash], hlist[mdb->ver]) { | 41 | hlist_for_each_entry_rcu(mp, p, &mdb->mhash[hash], hlist[mdb->ver]) { |
42 | if (dst == mp->addr) | 42 | if (dst == mp->addr) |
43 | return mp; | 43 | return mp; |
44 | } | 44 | } |
@@ -627,8 +627,8 @@ static void br_multicast_port_query_expired(unsigned long data) | |||
627 | struct net_bridge *br = port->br; | 627 | struct net_bridge *br = port->br; |
628 | 628 | ||
629 | spin_lock(&br->multicast_lock); | 629 | spin_lock(&br->multicast_lock); |
630 | if (port && (port->state == BR_STATE_DISABLED || | 630 | if (port->state == BR_STATE_DISABLED || |
631 | port->state == BR_STATE_BLOCKING)) | 631 | port->state == BR_STATE_BLOCKING) |
632 | goto out; | 632 | goto out; |
633 | 633 | ||
634 | if (port->multicast_startup_queries_sent < | 634 | if (port->multicast_startup_queries_sent < |
@@ -823,6 +823,7 @@ static int br_multicast_query(struct net_bridge *br, | |||
823 | unsigned long max_delay; | 823 | unsigned long max_delay; |
824 | unsigned long now = jiffies; | 824 | unsigned long now = jiffies; |
825 | __be32 group; | 825 | __be32 group; |
826 | int err = 0; | ||
826 | 827 | ||
827 | spin_lock(&br->multicast_lock); | 828 | spin_lock(&br->multicast_lock); |
828 | if (!netif_running(br->dev) || | 829 | if (!netif_running(br->dev) || |
@@ -841,12 +842,14 @@ static int br_multicast_query(struct net_bridge *br, | |||
841 | group = 0; | 842 | group = 0; |
842 | } | 843 | } |
843 | } else { | 844 | } else { |
844 | if (!pskb_may_pull(skb, sizeof(struct igmpv3_query))) | 845 | if (!pskb_may_pull(skb, sizeof(struct igmpv3_query))) { |
845 | return -EINVAL; | 846 | err = -EINVAL; |
847 | goto out; | ||
848 | } | ||
846 | 849 | ||
847 | ih3 = igmpv3_query_hdr(skb); | 850 | ih3 = igmpv3_query_hdr(skb); |
848 | if (ih3->nsrcs) | 851 | if (ih3->nsrcs) |
849 | return 0; | 852 | goto out; |
850 | 853 | ||
851 | max_delay = ih3->code ? 1 : | 854 | max_delay = ih3->code ? 1 : |
852 | IGMPV3_MRC(ih3->code) * (HZ / IGMP_TIMER_SCALE); | 855 | IGMPV3_MRC(ih3->code) * (HZ / IGMP_TIMER_SCALE); |
@@ -876,7 +879,7 @@ static int br_multicast_query(struct net_bridge *br, | |||
876 | 879 | ||
877 | out: | 880 | out: |
878 | spin_unlock(&br->multicast_lock); | 881 | spin_unlock(&br->multicast_lock); |
879 | return 0; | 882 | return err; |
880 | } | 883 | } |
881 | 884 | ||
882 | static void br_multicast_leave_group(struct net_bridge *br, | 885 | static void br_multicast_leave_group(struct net_bridge *br, |
@@ -1135,7 +1138,7 @@ void br_multicast_stop(struct net_bridge *br) | |||
1135 | 1138 | ||
1136 | if (mdb->old) { | 1139 | if (mdb->old) { |
1137 | spin_unlock_bh(&br->multicast_lock); | 1140 | spin_unlock_bh(&br->multicast_lock); |
1138 | synchronize_rcu_bh(); | 1141 | rcu_barrier_bh(); |
1139 | spin_lock_bh(&br->multicast_lock); | 1142 | spin_lock_bh(&br->multicast_lock); |
1140 | WARN_ON(mdb->old); | 1143 | WARN_ON(mdb->old); |
1141 | } | 1144 | } |