diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index cfba99b..5a09f13 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -73,6 +73,8 @@ static int ipip6_tunnel_init(struct net_device *dev);
 static void ipip6_tunnel_setup(struct net_device *dev);
 static void ipip6_dev_free(struct net_device *dev);
 static struct rtnl_link_ops sit_link_ops __read_mostly;
+static inline __be32 try_6rd(const struct in6_addr *v6dst,
+			     struct ip_tunnel *tunnel);
 
 static int sit_net_id __read_mostly;
 struct sit_net {
@@ -590,6 +592,22 @@ out:
 	return err;
 }
 
+static int sit_chk_encap_addr(struct ip_tunnel *tunnel, const __be32 *addr,
+			      const struct in6_addr *addr6)
+{
+#ifdef CONFIG_IPV6_SIT_6RD
+	if (ipv6_prefix_equal(addr6, &tunnel->ip6rd.prefix,
+			      tunnel->ip6rd.prefixlen) &&
+	    *addr != try_6rd(addr6, tunnel))
+		return 0;
+#else
+	if (addr6->s6_addr16[0] == htons(0x2002) &&
+	    *addr != try_6rd(addr6, tunnel))
+		return 0;
+#endif
+	return 1;
+}
+
 static int ipip6_rcv(struct sk_buff *skb)
 {
 	const struct iphdr *iph;
@@ -613,8 +631,15 @@ static int ipip6_rcv(struct sk_buff *skb)
 		skb->protocol = htons(ETH_P_IPV6);
 		skb->pkt_type = PACKET_HOST;
 
-		if ((tunnel->dev->priv_flags & IFF_ISATAP) &&
-		    !isatap_chksrc(skb, iph, tunnel)) {
+		if (tunnel->dev->priv_flags & IFF_ISATAP) {
+			if (!isatap_chksrc(skb, iph, tunnel)) {
+				tunnel->dev->stats.rx_errors++;
+				goto out;
+			}
+		} else if (!sit_chk_encap_addr(tunnel, &iph->saddr,
+					       &ipv6_hdr(skb)->saddr) ||
+			   !sit_chk_encap_addr(tunnel, &iph->daddr,
+					       &ipv6_hdr(skb)->daddr)) {
 			tunnel->dev->stats.rx_errors++;
 			goto out;
 		}
