extern struct raw_hashinfo raw_v4_hashinfo;
 struct sock *__raw_v4_lookup(struct net *net, struct sock *sk,
                             unsigned short num, __be32 raddr,
-                            __be32 laddr, int dif);
+                            __be32 laddr, int dif, int sdif);
 
 int raw_abort(struct sock *sk, int err);
 void raw_icmp_error(struct sk_buff *, int, u32);
 
 EXPORT_SYMBOL_GPL(raw_unhash_sk);
 
 struct sock *__raw_v4_lookup(struct net *net, struct sock *sk,
-               unsigned short num, __be32 raddr, __be32 laddr, int dif)
+                            unsigned short num, __be32 raddr, __be32 laddr,
+                            int dif, int sdif)
 {
        sk_for_each_from(sk) {
                struct inet_sock *inet = inet_sk(sk);
                if (net_eq(sock_net(sk), net) && inet->inet_num == num  &&
                    !(inet->inet_daddr && inet->inet_daddr != raddr)    &&
                    !(inet->inet_rcv_saddr && inet->inet_rcv_saddr != laddr) &&
-                   !(sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif))
+                   !(sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif &&
+                     sk->sk_bound_dev_if != sdif))
                        goto found; /* gotcha */
        }
        sk = NULL;
  */
 static int raw_v4_input(struct sk_buff *skb, const struct iphdr *iph, int hash)
 {
+       int sdif = inet_sdif(skb);
        struct sock *sk;
        struct hlist_head *head;
        int delivered = 0;
        net = dev_net(skb->dev);
        sk = __raw_v4_lookup(net, __sk_head(head), iph->protocol,
                             iph->saddr, iph->daddr,
-                            skb->dev->ifindex);
+                            skb->dev->ifindex, sdif);
 
        while (sk) {
                delivered = 1;
                }
                sk = __raw_v4_lookup(net, sk_next(sk), iph->protocol,
                                     iph->saddr, iph->daddr,
-                                    skb->dev->ifindex);
+                                    skb->dev->ifindex, sdif);
        }
 out:
        read_unlock(&raw_v4_hashinfo.lock);
        read_lock(&raw_v4_hashinfo.lock);
        raw_sk = sk_head(&raw_v4_hashinfo.ht[hash]);
        if (raw_sk) {
+               int dif = skb->dev->ifindex;
+               int sdif = inet_sdif(skb);
+
                iph = (const struct iphdr *)skb->data;
                net = dev_net(skb->dev);
 
                while ((raw_sk = __raw_v4_lookup(net, raw_sk, protocol,
                                                iph->daddr, iph->saddr,
-                                               skb->dev->ifindex)) != NULL) {
+                                               dif, sdif)) != NULL) {
                        raw_err(raw_sk, skb, info);
                        raw_sk = sk_next(raw_sk);
                        iph = (const struct iphdr *)skb->data;