* Must be invoked with rcu_read_lock
  */
 static struct ip_tunnel *ipip6_tunnel_lookup(struct net *net,
-               struct net_device *dev, __be32 remote, __be32 local)
+                                            struct net_device *dev,
+                                            __be32 remote, __be32 local,
+                                            int sifindex)
 {
        unsigned int h0 = HASH(remote);
        unsigned int h1 = HASH(local);
        struct ip_tunnel *t;
        struct sit_net *sitn = net_generic(net, sit_net_id);
+       int ifindex = dev ? dev->ifindex : 0;
 
        for_each_ip_tunnel_rcu(t, sitn->tunnels_r_l[h0 ^ h1]) {
                if (local == t->parms.iph.saddr &&
                    remote == t->parms.iph.daddr &&
-                   (!dev || !t->parms.link || dev->ifindex == t->parms.link) &&
+                   (!dev || !t->parms.link || ifindex == t->parms.link ||
+                    sifindex == t->parms.link) &&
                    (t->dev->flags & IFF_UP))
                        return t;
        }
        for_each_ip_tunnel_rcu(t, sitn->tunnels_r[h0]) {
                if (remote == t->parms.iph.daddr &&
-                   (!dev || !t->parms.link || dev->ifindex == t->parms.link) &&
+                   (!dev || !t->parms.link || ifindex == t->parms.link ||
+                    sifindex == t->parms.link) &&
                    (t->dev->flags & IFF_UP))
                        return t;
        }
        for_each_ip_tunnel_rcu(t, sitn->tunnels_l[h1]) {
                if (local == t->parms.iph.saddr &&
-                   (!dev || !t->parms.link || dev->ifindex == t->parms.link) &&
+                   (!dev || !t->parms.link || ifindex == t->parms.link ||
+                    sifindex == t->parms.link) &&
                    (t->dev->flags & IFF_UP))
                        return t;
        }
        const int code = icmp_hdr(skb)->code;
        unsigned int data_len = 0;
        struct ip_tunnel *t;
+       int sifindex;
        int err;
 
        switch (type) {
 
        err = -ENOENT;
 
-       t = ipip6_tunnel_lookup(dev_net(skb->dev),
-                               skb->dev,
-                               iph->daddr,
-                               iph->saddr);
+       sifindex = netif_is_l3_master(skb->dev) ? IPCB(skb)->iif : 0;
+       t = ipip6_tunnel_lookup(dev_net(skb->dev), skb->dev,
+                               iph->daddr, iph->saddr, sifindex);
        if (!t)
                goto out;
 
 {
        const struct iphdr *iph = ip_hdr(skb);
        struct ip_tunnel *tunnel;
+       int sifindex;
        int err;
 
+       sifindex = netif_is_l3_master(skb->dev) ? IPCB(skb)->iif : 0;
        tunnel = ipip6_tunnel_lookup(dev_net(skb->dev), skb->dev,
-                                    iph->saddr, iph->daddr);
+                                    iph->saddr, iph->daddr, sifindex);
        if (tunnel) {
                struct pcpu_sw_netstats *tstats;
 
 {
        const struct iphdr *iph;
        struct ip_tunnel *tunnel;
+       int sifindex;
+
+       sifindex = netif_is_l3_master(skb->dev) ? IPCB(skb)->iif : 0;
 
        iph = ip_hdr(skb);
        tunnel = ipip6_tunnel_lookup(dev_net(skb->dev), skb->dev,
-                                    iph->saddr, iph->daddr);
+                                    iph->saddr, iph->daddr, sifindex);
        if (tunnel) {
                const struct tnl_ptk_info *tpi;