net/mlx4_en: Fix mixed PFC and Global pause user control requests
[pandora-kernel.git] / net / bridge / br_netfilter.c
index d6ec372..6cdd3af 100644 (file)
@@ -114,12 +114,18 @@ static struct neighbour *fake_neigh_lookup(const struct dst_entry *dst, const vo
        return NULL;
 }
 
+static unsigned int fake_mtu(const struct dst_entry *dst)
+{
+       return dst->dev->mtu;
+}
+
 static struct dst_ops fake_dst_ops = {
        .family =               AF_INET,
        .protocol =             cpu_to_be16(ETH_P_IP),
        .update_pmtu =          fake_update_pmtu,
        .cow_metrics =          fake_cow_metrics,
        .neigh_lookup =         fake_neigh_lookup,
+       .mtu =                  fake_mtu,
 };
 
 /*
@@ -141,7 +147,7 @@ void br_netfilter_rtable_init(struct net_bridge *br)
        rt->dst.dev = br->dev;
        rt->dst.path = &rt->dst;
        dst_init_metrics(&rt->dst, br_dst_default_metrics, true);
-       rt->dst.flags   = DST_NOXFRM;
+       rt->dst.flags   = DST_NOXFRM | DST_NOPEER | DST_FAKE_RTABLE;
        rt->dst.ops = &fake_dst_ops;
 }
 
@@ -239,6 +245,9 @@ static int br_parse_ip_options(struct sk_buff *skb)
        struct net_device *dev = skb->dev;
        u32 len;
 
+       if (!pskb_may_pull(skb, sizeof(struct iphdr)))
+               goto inhdr_error;
+
        iph = ip_hdr(skb);
        opt = &(IPCB(skb)->opt);
 
@@ -681,11 +690,7 @@ static unsigned int br_nf_local_in(unsigned int hook, struct sk_buff *skb,
                                   const struct net_device *out,
                                   int (*okfn)(struct sk_buff *))
 {
-       struct rtable *rt = skb_rtable(skb);
-
-       if (rt && rt == bridge_parent_rtable(in))
-               skb_dst_drop(skb);
-
+       br_drop_fake_rtable(skb);
        return NF_ACCEPT;
 }
 
@@ -817,12 +822,15 @@ static int br_nf_dev_queue_xmit(struct sk_buff *skb)
            !skb_is_gso(skb)) {
                if (br_parse_ip_options(skb))
                        /* Drop invalid packet */
-                       return NF_DROP;
+                       goto drop;
                ret = ip_fragment(skb, br_dev_queue_push_xmit);
        } else
                ret = br_dev_queue_push_xmit(skb);
 
        return ret;
+ drop:
+       kfree_skb(skb);
+       return 0;
 }
 #else
 static int br_nf_dev_queue_xmit(struct sk_buff *skb)