]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - net/bridge/br_multicast.c
netfilter: bridge: use NFPROTO values for NF_HOOK invocation
[net-next-2.6.git] / net / bridge / br_multicast.c
index 2559fb539836fdf78e29387bfe57bad088b8a296..ed19b0a730ab62e1b025acb4787bd480df1df807 100644 (file)
@@ -38,7 +38,7 @@ static struct net_bridge_mdb_entry *__br_mdb_ip_get(
        struct net_bridge_mdb_entry *mp;
        struct hlist_node *p;
 
-       hlist_for_each_entry(mp, p, &mdb->mhash[hash], hlist[mdb->ver]) {
+       hlist_for_each_entry_rcu(mp, p, &mdb->mhash[hash], hlist[mdb->ver]) {
                if (dst == mp->addr)
                        return mp;
        }
@@ -49,22 +49,23 @@ static struct net_bridge_mdb_entry *__br_mdb_ip_get(
 static struct net_bridge_mdb_entry *br_mdb_ip_get(
        struct net_bridge_mdb_htable *mdb, __be32 dst)
 {
+       if (!mdb)
+               return NULL;
+
        return __br_mdb_ip_get(mdb, dst, br_ip_hash(mdb, dst));
 }
 
 struct net_bridge_mdb_entry *br_mdb_get(struct net_bridge *br,
                                        struct sk_buff *skb)
 {
-       struct net_bridge_mdb_htable *mdb = br->mdb;
-
-       if (!mdb || br->multicast_disabled)
+       if (br->multicast_disabled)
                return NULL;
 
        switch (skb->protocol) {
        case htons(ETH_P_IP):
                if (BR_INPUT_SKB_CB(skb)->igmp)
                        break;
-               return br_mdb_ip_get(mdb, ip_hdr(skb)->daddr);
+               return br_mdb_ip_get(br->mdb, ip_hdr(skb)->daddr);
        }
 
        return NULL;
@@ -607,7 +608,7 @@ static void br_multicast_send_query(struct net_bridge *br,
        if (port) {
                __skb_push(skb, sizeof(struct ethhdr));
                skb->dev = port->dev;
-               NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_OUT, skb, NULL, skb->dev,
+               NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_OUT, skb, NULL, skb->dev,
                        dev_queue_xmit);
        } else
                netif_rx(skb);
@@ -627,8 +628,8 @@ static void br_multicast_port_query_expired(unsigned long data)
        struct net_bridge *br = port->br;
 
        spin_lock(&br->multicast_lock);
-       if (port && (port->state == BR_STATE_DISABLED ||
-                    port->state == BR_STATE_BLOCKING))
+       if (port->state == BR_STATE_DISABLED ||
+           port->state == BR_STATE_BLOCKING)
                goto out;
 
        if (port->multicast_startup_queries_sent <
@@ -823,6 +824,7 @@ static int br_multicast_query(struct net_bridge *br,
        unsigned long max_delay;
        unsigned long now = jiffies;
        __be32 group;
+       int err = 0;
 
        spin_lock(&br->multicast_lock);
        if (!netif_running(br->dev) ||
@@ -841,15 +843,17 @@ static int br_multicast_query(struct net_bridge *br,
                        group = 0;
                }
        } else {
-               if (!pskb_may_pull(skb, sizeof(struct igmpv3_query)))
-                       return -EINVAL;
+               if (!pskb_may_pull(skb, sizeof(struct igmpv3_query))) {
+                       err = -EINVAL;
+                       goto out;
+               }
 
                ih3 = igmpv3_query_hdr(skb);
                if (ih3->nsrcs)
-                       return 0;
+                       goto out;
 
-               max_delay = ih3->code ? 1 :
-                           IGMPV3_MRC(ih3->code) * (HZ / IGMP_TIMER_SCALE);
+               max_delay = ih3->code ?
+                           IGMPV3_MRC(ih3->code) * (HZ / IGMP_TIMER_SCALE) : 1;
        }
 
        if (!group)
@@ -876,7 +880,7 @@ static int br_multicast_query(struct net_bridge *br,
 
 out:
        spin_unlock(&br->multicast_lock);
-       return 0;
+       return err;
 }
 
 static void br_multicast_leave_group(struct net_bridge *br,
@@ -987,7 +991,7 @@ static int br_multicast_ipv4_rcv(struct net_bridge *br,
 
                err = pskb_trim_rcsum(skb2, len);
                if (err)
-                       return err;
+                       goto err_out;
        }
 
        len -= ip_hdrlen(skb2);
@@ -1009,7 +1013,7 @@ static int br_multicast_ipv4_rcv(struct net_bridge *br,
        case CHECKSUM_NONE:
                skb2->csum = 0;
                if (skb_checksum_complete(skb2))
-                       return -EINVAL;
+                       goto out;
        }
 
        err = 0;
@@ -1036,6 +1040,7 @@ static int br_multicast_ipv4_rcv(struct net_bridge *br,
 
 out:
        __skb_push(skb2, offset);
+err_out:
        if (skb2 != skb)
                kfree_skb(skb2);
        return err;
@@ -1135,7 +1140,7 @@ void br_multicast_stop(struct net_bridge *br)
 
        if (mdb->old) {
                spin_unlock_bh(&br->multicast_lock);
-               synchronize_rcu_bh();
+               rcu_barrier_bh();
                spin_lock_bh(&br->multicast_lock);
                WARN_ON(mdb->old);
        }