diff options
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/datagram.c | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c index cc1139687fd7..2464a00e36ab 100644 --- a/net/ipv6/datagram.c +++ b/net/ipv6/datagram.c | |||
@@ -325,6 +325,16 @@ void ipv6_local_rxpmtu(struct sock *sk, struct flowi6 *fl6, u32 mtu) | |||
325 | kfree_skb(skb); | 325 | kfree_skb(skb); |
326 | } | 326 | } |
327 | 327 | ||
328 | static void ip6_datagram_prepare_pktinfo_errqueue(struct sk_buff *skb) | ||
329 | { | ||
330 | int ifindex = skb->dev ? skb->dev->ifindex : -1; | ||
331 | |||
332 | if (skb->protocol == htons(ETH_P_IPV6)) | ||
333 | IP6CB(skb)->iif = ifindex; | ||
334 | else | ||
335 | PKTINFO_SKB_CB(skb)->ipi_ifindex = ifindex; | ||
336 | } | ||
337 | |||
328 | /* | 338 | /* |
329 | * Handle MSG_ERRQUEUE | 339 | * Handle MSG_ERRQUEUE |
330 | */ | 340 | */ |
@@ -388,8 +398,12 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len) | |||
388 | sin->sin6_family = AF_INET6; | 398 | sin->sin6_family = AF_INET6; |
389 | sin->sin6_flowinfo = 0; | 399 | sin->sin6_flowinfo = 0; |
390 | sin->sin6_port = 0; | 400 | sin->sin6_port = 0; |
391 | if (np->rxopt.all) | 401 | if (np->rxopt.all) { |
402 | if (serr->ee.ee_origin != SO_EE_ORIGIN_ICMP && | ||
403 | serr->ee.ee_origin != SO_EE_ORIGIN_ICMP6) | ||
404 | ip6_datagram_prepare_pktinfo_errqueue(skb); | ||
392 | ip6_datagram_recv_common_ctl(sk, msg, skb); | 405 | ip6_datagram_recv_common_ctl(sk, msg, skb); |
406 | } | ||
393 | if (skb->protocol == htons(ETH_P_IPV6)) { | 407 | if (skb->protocol == htons(ETH_P_IPV6)) { |
394 | sin->sin6_addr = ipv6_hdr(skb)->saddr; | 408 | sin->sin6_addr = ipv6_hdr(skb)->saddr; |
395 | if (np->rxopt.all) | 409 | if (np->rxopt.all) |
@@ -491,7 +505,10 @@ void ip6_datagram_recv_common_ctl(struct sock *sk, struct msghdr *msg, | |||
491 | ipv6_addr_set_v4mapped(ip_hdr(skb)->daddr, | 505 | ipv6_addr_set_v4mapped(ip_hdr(skb)->daddr, |
492 | &src_info.ipi6_addr); | 506 | &src_info.ipi6_addr); |
493 | } | 507 | } |
494 | put_cmsg(msg, SOL_IPV6, IPV6_PKTINFO, sizeof(src_info), &src_info); | 508 | |
509 | if (src_info.ipi6_ifindex >= 0) | ||
510 | put_cmsg(msg, SOL_IPV6, IPV6_PKTINFO, | ||
511 | sizeof(src_info), &src_info); | ||
495 | } | 512 | } |
496 | } | 513 | } |
497 | 514 | ||