ipv6_sockglue.c (9d066a252786e1a18484a6283f82614d42a9f4ac) ipv6_sockglue.c (ceba1832b1b2da0149c51de62a847c00bca1677a)
1/*
2 * IPv6 BSD socket options interface
3 * Linux INET6 implementation
4 *
5 * Authors:
6 * Pedro Roque <roque@di.fc.ul.pt>
7 *
8 * Based on linux/net/ipv4/ip_sockglue.c

--- 84 unchanged lines hidden (view full) ---

93 new_ra->sel = sel;
94 new_ra->next = ra;
95 *rap = new_ra;
96 sock_hold(sk);
97 write_unlock_bh(&ip6_ra_lock);
98 return 0;
99}
100
1/*
2 * IPv6 BSD socket options interface
3 * Linux INET6 implementation
4 *
5 * Authors:
6 * Pedro Roque <roque@di.fc.ul.pt>
7 *
8 * Based on linux/net/ipv4/ip_sockglue.c

--- 84 unchanged lines hidden (view full) ---

93 new_ra->sel = sel;
94 new_ra->next = ra;
95 *rap = new_ra;
96 sock_hold(sk);
97 write_unlock_bh(&ip6_ra_lock);
98 return 0;
99}
100
101static
102struct ipv6_txoptions *ipv6_update_options(struct sock *sk,
103 struct ipv6_txoptions *opt)
104{
105 if (inet_sk(sk)->is_icsk) {
106 if (opt &&
107 !((1 << sk->sk_state) & (TCPF_LISTEN | TCPF_CLOSE)) &&
108 inet_sk(sk)->inet_daddr != LOOPBACK4_IPV6) {
109 struct inet_connection_sock *icsk = inet_csk(sk);

--- 292 unchanged lines hidden (view full) ---

402 optlen & 0x7 || optlen > 8 * 255)
403 goto e_inval;
404
405 /* hop-by-hop / destination options are privileged option */
406 retv = -EPERM;
407 if (optname != IPV6_RTHDR && !ns_capable(net->user_ns, CAP_NET_RAW))
408 break;
409
101struct ipv6_txoptions *ipv6_update_options(struct sock *sk,
102 struct ipv6_txoptions *opt)
103{
104 if (inet_sk(sk)->is_icsk) {
105 if (opt &&
106 !((1 << sk->sk_state) & (TCPF_LISTEN | TCPF_CLOSE)) &&
107 inet_sk(sk)->inet_daddr != LOOPBACK4_IPV6) {
108 struct inet_connection_sock *icsk = inet_csk(sk);

--- 292 unchanged lines hidden (view full) ---

401 optlen & 0x7 || optlen > 8 * 255)
402 goto e_inval;
403
404 /* hop-by-hop / destination options are privileged option */
405 retv = -EPERM;
406 if (optname != IPV6_RTHDR && !ns_capable(net->user_ns, CAP_NET_RAW))
407 break;
408
410 opt = rcu_dereference_protected(np->opt,
411 lockdep_sock_is_held(sk));
409 opt = rcu_dereference_protected(np->opt, sock_owned_by_user(sk));
412 opt = ipv6_renew_options(sk, opt, optname,
413 (struct ipv6_opt_hdr __user *)optval,
414 optlen);
415 if (IS_ERR(opt)) {
416 retv = PTR_ERR(opt);
417 break;
418 }
419

--- 47 unchanged lines hidden (view full) ---

467 break;
468 }
469
470 case IPV6_2292PKTOPTIONS:
471 {
472 struct ipv6_txoptions *opt = NULL;
473 struct msghdr msg;
474 struct flowi6 fl6;
410 opt = ipv6_renew_options(sk, opt, optname,
411 (struct ipv6_opt_hdr __user *)optval,
412 optlen);
413 if (IS_ERR(opt)) {
414 retv = PTR_ERR(opt);
415 break;
416 }
417

--- 47 unchanged lines hidden (view full) ---

465 break;
466 }
467
468 case IPV6_2292PKTOPTIONS:
469 {
470 struct ipv6_txoptions *opt = NULL;
471 struct msghdr msg;
472 struct flowi6 fl6;
475 struct sockcm_cookie sockc_junk;
476 struct ipcm6_cookie ipc6;
473 int junk;
477
478 memset(&fl6, 0, sizeof(fl6));
479 fl6.flowi6_oif = sk->sk_bound_dev_if;
480 fl6.flowi6_mark = sk->sk_mark;
481
482 if (optlen == 0)
483 goto update;
484

--- 13 unchanged lines hidden (view full) ---

498 atomic_set(&opt->refcnt, 1);
499 opt->tot_len = sizeof(*opt) + optlen;
500 retv = -EFAULT;
501 if (copy_from_user(opt+1, optval, optlen))
502 goto done;
503
504 msg.msg_controllen = optlen;
505 msg.msg_control = (void *)(opt+1);
474
475 memset(&fl6, 0, sizeof(fl6));
476 fl6.flowi6_oif = sk->sk_bound_dev_if;
477 fl6.flowi6_mark = sk->sk_mark;
478
479 if (optlen == 0)
480 goto update;
481

--- 13 unchanged lines hidden (view full) ---

495 atomic_set(&opt->refcnt, 1);
496 opt->tot_len = sizeof(*opt) + optlen;
497 retv = -EFAULT;
498 if (copy_from_user(opt+1, optval, optlen))
499 goto done;
500
501 msg.msg_controllen = optlen;
502 msg.msg_control = (void *)(opt+1);
506 ipc6.opt = opt;
507
503
508 retv = ip6_datagram_send_ctl(net, sk, &msg, &fl6, &ipc6, &sockc_junk);
504 retv = ip6_datagram_send_ctl(net, sk, &msg, &fl6, opt, &junk,
505 &junk, &junk);
509 if (retv)
510 goto done;
511update:
512 retv = 0;
513 opt = ipv6_update_options(sk, opt);
514done:
515 if (opt) {
516 atomic_sub(opt->tot_len, &sk->sk_omem_alloc);

--- 603 unchanged lines hidden (view full) ---

1120 case IPV6_HOPOPTS:
1121 case IPV6_RTHDRDSTOPTS:
1122 case IPV6_RTHDR:
1123 case IPV6_DSTOPTS:
1124 {
1125 struct ipv6_txoptions *opt;
1126
1127 lock_sock(sk);
506 if (retv)
507 goto done;
508update:
509 retv = 0;
510 opt = ipv6_update_options(sk, opt);
511done:
512 if (opt) {
513 atomic_sub(opt->tot_len, &sk->sk_omem_alloc);

--- 603 unchanged lines hidden (view full) ---

1117 case IPV6_HOPOPTS:
1118 case IPV6_RTHDRDSTOPTS:
1119 case IPV6_RTHDR:
1120 case IPV6_DSTOPTS:
1121 {
1122 struct ipv6_txoptions *opt;
1123
1124 lock_sock(sk);
1128 opt = rcu_dereference_protected(np->opt,
1129 lockdep_sock_is_held(sk));
1125 opt = rcu_dereference_protected(np->opt, sock_owned_by_user(sk));
1130 len = ipv6_getsockopt_sticky(sk, opt, optname, optval, len);
1131 release_sock(sk);
1132 /* check if ipv6_getsockopt_sticky() returns err code */
1133 if (len < 0)
1134 return len;
1135 return put_user(len, optlen);
1136 }
1137

--- 261 unchanged lines hidden ---
1126 len = ipv6_getsockopt_sticky(sk, opt, optname, optval, len);
1127 release_sock(sk);
1128 /* check if ipv6_getsockopt_sticky() returns err code */
1129 if (len < 0)
1130 return len;
1131 return put_user(len, optlen);
1132 }
1133

--- 261 unchanged lines hidden ---