[IPV6]: Share common code-paths for sticky socket options.
Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
cee8947338
commit
e7712f1a7c
|
@ -103,6 +103,29 @@ int ip6_ra_control(struct sock *sk, int sel, void (*destructor)(struct sock *))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
struct ipv6_txoptions *ipv6_update_options(struct sock *sk,
|
||||||
|
struct ipv6_txoptions *opt)
|
||||||
|
{
|
||||||
|
if (inet_sk(sk)->is_icsk) {
|
||||||
|
if (opt &&
|
||||||
|
!((1 << sk->sk_state) & (TCPF_LISTEN | TCPF_CLOSE)) &&
|
||||||
|
inet_sk(sk)->daddr != LOOPBACK4_IPV6) {
|
||||||
|
struct inet_connection_sock *icsk = inet_csk(sk);
|
||||||
|
icsk->icsk_ext_hdr_len = opt->opt_flen + opt->opt_nflen;
|
||||||
|
icsk->icsk_sync_mss(sk, icsk->icsk_pmtu_cookie);
|
||||||
|
}
|
||||||
|
opt = xchg(&inet6_sk(sk)->opt, opt);
|
||||||
|
} else {
|
||||||
|
write_lock(&sk->sk_dst_lock);
|
||||||
|
opt = xchg(&inet6_sk(sk)->opt, opt);
|
||||||
|
write_unlock(&sk->sk_dst_lock);
|
||||||
|
}
|
||||||
|
sk_dst_reset(sk);
|
||||||
|
|
||||||
|
return opt;
|
||||||
|
}
|
||||||
|
|
||||||
static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
|
static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
|
||||||
char __user *optval, int optlen)
|
char __user *optval, int optlen)
|
||||||
{
|
{
|
||||||
|
@ -351,25 +374,7 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
|
||||||
}
|
}
|
||||||
|
|
||||||
retv = 0;
|
retv = 0;
|
||||||
if (inet_sk(sk)->is_icsk) {
|
opt = ipv6_update_options(sk, opt);
|
||||||
if (opt) {
|
|
||||||
struct inet_connection_sock *icsk = inet_csk(sk);
|
|
||||||
if (!((1 << sk->sk_state) &
|
|
||||||
(TCPF_LISTEN | TCPF_CLOSE))
|
|
||||||
&& inet_sk(sk)->daddr != LOOPBACK4_IPV6) {
|
|
||||||
icsk->icsk_ext_hdr_len =
|
|
||||||
opt->opt_flen + opt->opt_nflen;
|
|
||||||
icsk->icsk_sync_mss(sk, icsk->icsk_pmtu_cookie);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
opt = xchg(&np->opt, opt);
|
|
||||||
sk_dst_reset(sk);
|
|
||||||
} else {
|
|
||||||
write_lock(&sk->sk_dst_lock);
|
|
||||||
opt = xchg(&np->opt, opt);
|
|
||||||
write_unlock(&sk->sk_dst_lock);
|
|
||||||
sk_dst_reset(sk);
|
|
||||||
}
|
|
||||||
sticky_done:
|
sticky_done:
|
||||||
if (opt)
|
if (opt)
|
||||||
sock_kfree_s(sk, opt, opt->tot_len);
|
sock_kfree_s(sk, opt, opt->tot_len);
|
||||||
|
@ -415,26 +420,7 @@ sticky_done:
|
||||||
goto done;
|
goto done;
|
||||||
update:
|
update:
|
||||||
retv = 0;
|
retv = 0;
|
||||||
if (inet_sk(sk)->is_icsk) {
|
opt = ipv6_update_options(sk, opt);
|
||||||
if (opt) {
|
|
||||||
struct inet_connection_sock *icsk = inet_csk(sk);
|
|
||||||
if (!((1 << sk->sk_state) &
|
|
||||||
(TCPF_LISTEN | TCPF_CLOSE))
|
|
||||||
&& inet_sk(sk)->daddr != LOOPBACK4_IPV6) {
|
|
||||||
icsk->icsk_ext_hdr_len =
|
|
||||||
opt->opt_flen + opt->opt_nflen;
|
|
||||||
icsk->icsk_sync_mss(sk, icsk->icsk_pmtu_cookie);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
opt = xchg(&np->opt, opt);
|
|
||||||
sk_dst_reset(sk);
|
|
||||||
} else {
|
|
||||||
write_lock(&sk->sk_dst_lock);
|
|
||||||
opt = xchg(&np->opt, opt);
|
|
||||||
write_unlock(&sk->sk_dst_lock);
|
|
||||||
sk_dst_reset(sk);
|
|
||||||
}
|
|
||||||
|
|
||||||
done:
|
done:
|
||||||
if (opt)
|
if (opt)
|
||||||
sock_kfree_s(sk, opt, opt->tot_len);
|
sock_kfree_s(sk, opt, opt->tot_len);
|
||||||
|
|
Loading…
Reference in New Issue