diff options
| author | YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org> | 2008-04-14 02:21:52 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2008-04-14 02:21:52 -0400 |
| commit | e7712f1a7c32a5533be25ed806b1a8f7e42b452a (patch) | |
| tree | 33996145bc3e087831bf6b11c2afa8baf0d8cf20 | |
| parent | cee8947338d46bccece54c752bf6cd4043035f05 (diff) | |
[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>
| -rw-r--r-- | net/ipv6/ipv6_sockglue.c | 64 |
1 files changed, 25 insertions, 39 deletions
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index 2f1244dc5ebf..06de9d0e1f6b 100644 --- a/net/ipv6/ipv6_sockglue.c +++ b/net/ipv6/ipv6_sockglue.c | |||
| @@ -103,6 +103,29 @@ int ip6_ra_control(struct sock *sk, int sel, void (*destructor)(struct sock *)) | |||
| 103 | return 0; | 103 | return 0; |
| 104 | } | 104 | } |
| 105 | 105 | ||
| 106 | static | ||
| 107 | struct ipv6_txoptions *ipv6_update_options(struct sock *sk, | ||
| 108 | struct ipv6_txoptions *opt) | ||
| 109 | { | ||
| 110 | if (inet_sk(sk)->is_icsk) { | ||
| 111 | if (opt && | ||
| 112 | !((1 << sk->sk_state) & (TCPF_LISTEN | TCPF_CLOSE)) && | ||
| 113 | inet_sk(sk)->daddr != LOOPBACK4_IPV6) { | ||
| 114 | struct inet_connection_sock *icsk = inet_csk(sk); | ||
| 115 | icsk->icsk_ext_hdr_len = opt->opt_flen + opt->opt_nflen; | ||
| 116 | icsk->icsk_sync_mss(sk, icsk->icsk_pmtu_cookie); | ||
| 117 | } | ||
| 118 | opt = xchg(&inet6_sk(sk)->opt, opt); | ||
| 119 | } else { | ||
| 120 | write_lock(&sk->sk_dst_lock); | ||
| 121 | opt = xchg(&inet6_sk(sk)->opt, opt); | ||
| 122 | write_unlock(&sk->sk_dst_lock); | ||
| 123 | } | ||
| 124 | sk_dst_reset(sk); | ||
| 125 | |||
| 126 | return opt; | ||
| 127 | } | ||
| 128 | |||
| 106 | static int do_ipv6_setsockopt(struct sock *sk, int level, int optname, | 129 | static int do_ipv6_setsockopt(struct sock *sk, int level, int optname, |
| 107 | char __user *optval, int optlen) | 130 | char __user *optval, int optlen) |
| 108 | { | 131 | { |
| @@ -351,25 +374,7 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname, | |||
| 351 | } | 374 | } |
| 352 | 375 | ||
| 353 | retv = 0; | 376 | retv = 0; |
| 354 | if (inet_sk(sk)->is_icsk) { | 377 | opt = ipv6_update_options(sk, opt); |
| 355 | if (opt) { | ||
| 356 | struct inet_connection_sock *icsk = inet_csk(sk); | ||
| 357 | if (!((1 << sk->sk_state) & | ||
| 358 | (TCPF_LISTEN | TCPF_CLOSE)) | ||
| 359 | && inet_sk(sk)->daddr != LOOPBACK4_IPV6) { | ||
| 360 | icsk->icsk_ext_hdr_len = | ||
| 361 | opt->opt_flen + opt->opt_nflen; | ||
| 362 | icsk->icsk_sync_mss(sk, icsk->icsk_pmtu_cookie); | ||
| 363 | } | ||
| 364 | } | ||
| 365 | opt = xchg(&np->opt, opt); | ||
| 366 | sk_dst_reset(sk); | ||
| 367 | } else { | ||
| 368 | write_lock(&sk->sk_dst_lock); | ||
| 369 | opt = xchg(&np->opt, opt); | ||
| 370 | write_unlock(&sk->sk_dst_lock); | ||
| 371 | sk_dst_reset(sk); | ||
| 372 | } | ||
| 373 | sticky_done: | 378 | sticky_done: |
| 374 | if (opt) | 379 | if (opt) |
| 375 | sock_kfree_s(sk, opt, opt->tot_len); | 380 | sock_kfree_s(sk, opt, opt->tot_len); |
| @@ -415,26 +420,7 @@ sticky_done: | |||
| 415 | goto done; | 420 | goto done; |
| 416 | update: | 421 | update: |
| 417 | retv = 0; | 422 | retv = 0; |
| 418 | if (inet_sk(sk)->is_icsk) { | 423 | opt = ipv6_update_options(sk, opt); |
| 419 | if (opt) { | ||
| 420 | struct inet_connection_sock *icsk = inet_csk(sk); | ||
| 421 | if (!((1 << sk->sk_state) & | ||
| 422 | (TCPF_LISTEN | TCPF_CLOSE)) | ||
| 423 | && inet_sk(sk)->daddr != LOOPBACK4_IPV6) { | ||
| 424 | icsk->icsk_ext_hdr_len = | ||
| 425 | opt->opt_flen + opt->opt_nflen; | ||
| 426 | icsk->icsk_sync_mss(sk, icsk->icsk_pmtu_cookie); | ||
| 427 | } | ||
| 428 | } | ||
| 429 | opt = xchg(&np->opt, opt); | ||
| 430 | sk_dst_reset(sk); | ||
| 431 | } else { | ||
| 432 | write_lock(&sk->sk_dst_lock); | ||
| 433 | opt = xchg(&np->opt, opt); | ||
| 434 | write_unlock(&sk->sk_dst_lock); | ||
| 435 | sk_dst_reset(sk); | ||
| 436 | } | ||
| 437 | |||
| 438 | done: | 424 | done: |
| 439 | if (opt) | 425 | if (opt) |
| 440 | sock_kfree_s(sk, opt, opt->tot_len); | 426 | sock_kfree_s(sk, opt, opt->tot_len); |
