Merge tag 'v3.10.95' into update
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / net / ipv6 / reassembly.c
index 1aeb473b2cc695d8d2b0a3696972ec9228455d14..a1fb511da3b5bd0ded7cfcdb090d88f0d6e06968 100644 (file)
@@ -111,7 +111,10 @@ bool ip6_frag_match(struct inet_frag_queue *q, void *a)
        return  fq->id == arg->id &&
                fq->user == arg->user &&
                ipv6_addr_equal(&fq->saddr, arg->src) &&
-               ipv6_addr_equal(&fq->daddr, arg->dst);
+               ipv6_addr_equal(&fq->daddr, arg->dst) &&
+               (arg->iif == fq->iif ||
+                !(ipv6_addr_type(arg->dst) & (IPV6_ADDR_MULTICAST |
+                                              IPV6_ADDR_LINKLOCAL)));
 }
 EXPORT_SYMBOL(ip6_frag_match);
 
@@ -180,7 +183,7 @@ static void ip6_frag_expire(unsigned long data)
 
 static __inline__ struct frag_queue *
 fq_find(struct net *net, __be32 id, const struct in6_addr *src,
-       const struct in6_addr *dst, u8 ecn)
+       const struct in6_addr *dst, int iif, u8 ecn)
 {
        struct inet_frag_queue *q;
        struct ip6_create_arg arg;
@@ -190,6 +193,7 @@ fq_find(struct net *net, __be32 id, const struct in6_addr *src,
        arg.user = IP6_DEFRAG_LOCAL_DELIVER;
        arg.src = src;
        arg.dst = dst;
+       arg.iif = iif;
        arg.ecn = ecn;
 
        read_lock(&ip6_frags.lock);
@@ -558,7 +562,7 @@ static int ipv6_frag_rcv(struct sk_buff *skb)
                                 IPSTATS_MIB_REASMFAILS, evicted);
 
        fq = fq_find(net, fhdr->identification, &hdr->saddr, &hdr->daddr,
-                    ip6_frag_ecn(hdr));
+                    skb->dev ? skb->dev->ifindex : 0, ip6_frag_ecn(hdr));
        if (fq != NULL) {
                int ret;