| .. | .. |
|---|
| 429 | 429 | if (optlen < sizeof(int)) |
|---|
| 430 | 430 | goto e_inval; |
|---|
| 431 | 431 | if (val == PF_INET) { |
|---|
| 432 | | - struct ipv6_txoptions *opt; |
|---|
| 433 | | - struct sk_buff *pktopt; |
|---|
| 434 | | - |
|---|
| 435 | 432 | if (sk->sk_type == SOCK_RAW) |
|---|
| 436 | 433 | break; |
|---|
| 437 | 434 | |
|---|
| .. | .. |
|---|
| 462 | 459 | break; |
|---|
| 463 | 460 | } |
|---|
| 464 | 461 | |
|---|
| 465 | | - fl6_free_socklist(sk); |
|---|
| 466 | 462 | __ipv6_sock_mc_close(sk); |
|---|
| 467 | 463 | __ipv6_sock_ac_close(sk); |
|---|
| 468 | 464 | |
|---|
| .. | .. |
|---|
| 497 | 493 | sk->sk_socket->ops = &inet_dgram_ops; |
|---|
| 498 | 494 | sk->sk_family = PF_INET; |
|---|
| 499 | 495 | } |
|---|
| 500 | | - opt = xchg((__force struct ipv6_txoptions **)&np->opt, |
|---|
| 501 | | - NULL); |
|---|
| 502 | | - if (opt) { |
|---|
| 503 | | - atomic_sub(opt->tot_len, &sk->sk_omem_alloc); |
|---|
| 504 | | - txopt_put(opt); |
|---|
| 505 | | - } |
|---|
| 506 | | - pktopt = xchg(&np->pktoptions, NULL); |
|---|
| 507 | | - kfree_skb(pktopt); |
|---|
| 496 | + |
|---|
| 497 | + /* Disable all options not to allocate memory anymore, |
|---|
| 498 | + * but there is still a race. See the lockless path |
|---|
| 499 | + * in udpv6_sendmsg() and ipv6_local_rxpmtu(). |
|---|
| 500 | + */ |
|---|
| 501 | + np->rxopt.all = 0; |
|---|
| 502 | + |
|---|
| 503 | + inet6_cleanup_sock(sk); |
|---|
| 508 | 504 | |
|---|
| 509 | 505 | /* |
|---|
| 510 | 506 | * ... and add it to the refcnt debug socks count |
|---|