Merge commit 'v2.6.32-rc7'
[safe/jmp/linux-2.6] / net / bridge / br_forward.c
index bdd9cce..bc1704a 100644 (file)
@@ -22,7 +22,8 @@
 static inline int should_deliver(const struct net_bridge_port *p,
                                 const struct sk_buff *skb)
 {
-       return (skb->dev != p->dev && p->state == BR_STATE_FORWARDING);
+       return (((p->flags & BR_HAIRPIN_MODE) || skb->dev != p->dev) &&
+               p->state == BR_STATE_FORWARDING);
 }
 
 static inline unsigned packet_length(const struct sk_buff *skb)
@@ -67,6 +68,11 @@ static void __br_forward(const struct net_bridge_port *to, struct sk_buff *skb)
 {
        struct net_device *indev;
 
+       if (skb_warn_if_lro(skb)) {
+               kfree_skb(skb);
+               return;
+       }
+
        indev = skb->dev;
        skb->dev = to->dev;
        skb_forward_csum(skb);
@@ -89,7 +95,7 @@ void br_deliver(const struct net_bridge_port *to, struct sk_buff *skb)
 /* called with rcu_read_lock */
 void br_forward(const struct net_bridge_port *to, struct sk_buff *skb)
 {
-       if (!skb_warn_if_lro(skb) && should_deliver(to, skb)) {
+       if (should_deliver(to, skb)) {
                __br_forward(to, skb);
                return;
        }