diff options
-rw-r--r-- | include/linux/ipv6.h | 1 | ||||
-rw-r--r-- | net/ipv6/ipv6_sockglue.c | 22 |
2 files changed, 23 insertions, 0 deletions
diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h index 641e026eee8f..0b816cae533e 100644 --- a/include/linux/ipv6.h +++ b/include/linux/ipv6.h | |||
@@ -278,6 +278,7 @@ struct ipv6_pinfo { | |||
278 | struct in6_addr saddr; | 278 | struct in6_addr saddr; |
279 | struct in6_addr rcv_saddr; | 279 | struct in6_addr rcv_saddr; |
280 | struct in6_addr daddr; | 280 | struct in6_addr daddr; |
281 | struct in6_pktinfo sticky_pktinfo; | ||
281 | struct in6_addr *daddr_cache; | 282 | struct in6_addr *daddr_cache; |
282 | #ifdef CONFIG_IPV6_SUBTREES | 283 | #ifdef CONFIG_IPV6_SUBTREES |
283 | struct in6_addr *saddr_cache; | 284 | struct in6_addr *saddr_cache; |
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index 2aa294be0c79..0feaee38bc37 100644 --- a/net/ipv6/ipv6_sockglue.c +++ b/net/ipv6/ipv6_sockglue.c | |||
@@ -395,6 +395,28 @@ sticky_done: | |||
395 | break; | 395 | break; |
396 | } | 396 | } |
397 | 397 | ||
398 | case IPV6_PKTINFO: | ||
399 | { | ||
400 | struct in6_pktinfo pkt; | ||
401 | |||
402 | if (optlen == 0) | ||
403 | goto e_inval; | ||
404 | else if (optlen < sizeof(struct in6_pktinfo) || optval == NULL) | ||
405 | goto e_inval; | ||
406 | |||
407 | if (copy_from_user(&pkt, optval, optlen)) { | ||
408 | retv = -EFAULT; | ||
409 | break; | ||
410 | } | ||
411 | if (sk->sk_bound_dev_if && pkt.ipi6_ifindex != sk->sk_bound_dev_if) | ||
412 | goto e_inval; | ||
413 | |||
414 | np->sticky_pktinfo.ipi6_ifindex = pkt.ipi6_ifindex; | ||
415 | ipv6_addr_copy(&np->sticky_pktinfo.ipi6_addr, &pkt.ipi6_addr); | ||
416 | retv = 0; | ||
417 | break; | ||
418 | } | ||
419 | |||
398 | case IPV6_2292PKTOPTIONS: | 420 | case IPV6_2292PKTOPTIONS: |
399 | { | 421 | { |
400 | struct ipv6_txoptions *opt = NULL; | 422 | struct ipv6_txoptions *opt = NULL; |