@@ -122,15 +122,17 @@ void raw_unhash_sk(struct sock *sk)
122
122
EXPORT_SYMBOL_GPL (raw_unhash_sk );
123
123
124
124
struct sock * __raw_v4_lookup (struct net * net , struct sock * sk ,
125
- unsigned short num , __be32 raddr , __be32 laddr , int dif )
125
+ unsigned short num , __be32 raddr , __be32 laddr ,
126
+ int dif , int sdif )
126
127
{
127
128
sk_for_each_from (sk ) {
128
129
struct inet_sock * inet = inet_sk (sk );
129
130
130
131
if (net_eq (sock_net (sk ), net ) && inet -> inet_num == num &&
131
132
!(inet -> inet_daddr && inet -> inet_daddr != raddr ) &&
132
133
!(inet -> inet_rcv_saddr && inet -> inet_rcv_saddr != laddr ) &&
133
- !(sk -> sk_bound_dev_if && sk -> sk_bound_dev_if != dif ))
134
+ !(sk -> sk_bound_dev_if && sk -> sk_bound_dev_if != dif &&
135
+ sk -> sk_bound_dev_if != sdif ))
134
136
goto found ; /* gotcha */
135
137
}
136
138
sk = NULL ;
@@ -171,6 +173,7 @@ static int icmp_filter(const struct sock *sk, const struct sk_buff *skb)
171
173
*/
172
174
static int raw_v4_input (struct sk_buff * skb , const struct iphdr * iph , int hash )
173
175
{
176
+ int sdif = inet_sdif (skb );
174
177
struct sock * sk ;
175
178
struct hlist_head * head ;
176
179
int delivered = 0 ;
@@ -184,7 +187,7 @@ static int raw_v4_input(struct sk_buff *skb, const struct iphdr *iph, int hash)
184
187
net = dev_net (skb -> dev );
185
188
sk = __raw_v4_lookup (net , __sk_head (head ), iph -> protocol ,
186
189
iph -> saddr , iph -> daddr ,
187
- skb -> dev -> ifindex );
190
+ skb -> dev -> ifindex , sdif );
188
191
189
192
while (sk ) {
190
193
delivered = 1 ;
@@ -199,7 +202,7 @@ static int raw_v4_input(struct sk_buff *skb, const struct iphdr *iph, int hash)
199
202
}
200
203
sk = __raw_v4_lookup (net , sk_next (sk ), iph -> protocol ,
201
204
iph -> saddr , iph -> daddr ,
202
- skb -> dev -> ifindex );
205
+ skb -> dev -> ifindex , sdif );
203
206
}
204
207
out :
205
208
read_unlock (& raw_v4_hashinfo .lock );
@@ -297,12 +300,15 @@ void raw_icmp_error(struct sk_buff *skb, int protocol, u32 info)
297
300
read_lock (& raw_v4_hashinfo .lock );
298
301
raw_sk = sk_head (& raw_v4_hashinfo .ht [hash ]);
299
302
if (raw_sk ) {
303
+ int dif = skb -> dev -> ifindex ;
304
+ int sdif = inet_sdif (skb );
305
+
300
306
iph = (const struct iphdr * )skb -> data ;
301
307
net = dev_net (skb -> dev );
302
308
303
309
while ((raw_sk = __raw_v4_lookup (net , raw_sk , protocol ,
304
310
iph -> daddr , iph -> saddr ,
305
- skb -> dev -> ifindex )) != NULL ) {
311
+ dif , sdif )) != NULL ) {
306
312
raw_err (raw_sk , skb , info );
307
313
raw_sk = sk_next (raw_sk );
308
314
iph = (const struct iphdr * )skb -> data ;
0 commit comments