Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'sctp-avoid-redundant-initialisation-in-sctp_accept-and-sctp_do_peeloff'

Kuniyuki Iwashima says:

====================
sctp: Avoid redundant initialisation in sctp_accept() and sctp_do_peeloff().

When sctp_accept() and sctp_do_peeloff() allocates a new socket,
somehow sk_alloc() is used, and the new socket goes through full
initialisation, but most of the fields are overwritten later.

1)
sctp_accept()
|- sctp_v[46]_create_accept_sk()
| |- sk_alloc()
| |- sock_init_data()
| |- sctp_copy_sock()
| `- newsk->sk_prot->init() / sctp_init_sock()
|
`- sctp_sock_migrate()
`- sctp_copy_descendant(newsk, oldsk)

sock_init_data() initialises struct sock, but many fields are
overwritten by sctp_copy_sock(), which inherits fields of struct
sock and inet_sock from the parent socket.

sctp_init_sock() fully initialises struct sctp_sock, but later
sctp_copy_descendant() inherits most fields from the parent's
struct sctp_sock by memcpy().

2)
sctp_do_peeloff()
|- sock_create()
| |
| ...
| |- sk_alloc()
| |- sock_init_data()
| ...
| `- newsk->sk_prot->init() / sctp_init_sock()
|
|- sctp_copy_sock()
`- sctp_sock_migrate()
`- sctp_copy_descendant(newsk, oldsk)

sock_create() creates a brand new socket, but sctp_copy_sock()
and sctp_sock_migrate() overwrite most of the fields.

So, sk_alloc(), sock_init_data(), sctp_copy_sock(), and
sctp_copy_descendant() can be replaced with a single function
like sk_clone_lock().

This series does the conversion and removes TODO comment added
by commit 4a997d49d92ad ("tcp: Save lock_sock() for memcg in
inet_csk_accept().").

Tested accept() and SCTP_SOCKOPT_PEELOFF and both work properly.

socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP) = 3
bind(3, {sa_family=AF_INET, sin_port=htons(0), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
listen(3, -1) = 0
getsockname(3, {sa_family=AF_INET, sin_port=htons(49460), sin_addr=inet_addr("127.0.0.1")}, [16]) = 0
socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP) = 4
connect(4, {sa_family=AF_INET, sin_port=htons(49460), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
accept(3, NULL, NULL) = 5
...
socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP) = 3
bind(3, {sa_family=AF_INET, sin_port=htons(0), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
listen(3, -1) = 0
getsockname(3, {sa_family=AF_INET, sin_port=htons(48240), sin_addr=inet_addr("127.0.0.1")}, [16]) = 0
socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP) = 4
connect(4, {sa_family=AF_INET, sin_port=htons(48240), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
getsockopt(3, SOL_SCTP, SCTP_SOCKOPT_PEELOFF, "*\0\0\0\5\0\0\0", [8]) = 5

v1: https://lore.kernel.org/20251021214422.1941691-1-kuniyu@google.com
====================

Link: https://patch.msgid.link/20251023231751.4168390-1-kuniyu@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+118 -225
-8
include/net/inet_sock.h
··· 355 355 356 356 #define inet_sk(ptr) container_of_const(ptr, struct inet_sock, sk) 357 357 358 - static inline void __inet_sk_copy_descendant(struct sock *sk_to, 359 - const struct sock *sk_from, 360 - const int ancestor_size) 361 - { 362 - memcpy(inet_sk(sk_to) + 1, inet_sk(sk_from) + 1, 363 - sk_from->sk_prot->obj_size - ancestor_size); 364 - } 365 - 366 358 int inet_sk_rebuild_header(struct sock *sk); 367 359 368 360 /**
+1 -2
include/net/sctp/sctp.h
··· 94 94 __poll_t sctp_poll(struct file *file, struct socket *sock, 95 95 poll_table *wait); 96 96 void sctp_sock_rfree(struct sk_buff *skb); 97 - void sctp_copy_sock(struct sock *newsk, struct sock *sk, 98 - struct sctp_association *asoc); 97 + 99 98 extern struct percpu_counter sctp_sockets_allocated; 100 99 int sctp_asconf_mgmt(struct sctp_sock *, struct sctp_sockaddr_entry *); 101 100 struct sk_buff *sctp_skb_recv_datagram(struct sock *, int, int *);
-3
include/net/sctp/structs.h
··· 497 497 int (*bind_verify) (struct sctp_sock *, union sctp_addr *); 498 498 int (*send_verify) (struct sctp_sock *, union sctp_addr *); 499 499 int (*supported_addrs)(const struct sctp_sock *, __be16 *); 500 - struct sock *(*create_accept_sk) (struct sock *sk, 501 - struct sctp_association *asoc, 502 - bool kern); 503 500 int (*addr_to_user)(struct sctp_sock *sk, union sctp_addr *addr); 504 501 void (*to_sk_saddr)(union sctp_addr *, struct sock *sk); 505 502 void (*to_sk_daddr)(union sctp_addr *, struct sock *sk);
+6 -1
include/net/sock.h
··· 1822 1822 void sk_free(struct sock *sk); 1823 1823 void sk_net_refcnt_upgrade(struct sock *sk); 1824 1824 void sk_destruct(struct sock *sk); 1825 - struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority); 1825 + struct sock *sk_clone(const struct sock *sk, const gfp_t priority, bool lock); 1826 + 1827 + static inline struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority) 1828 + { 1829 + return sk_clone(sk, priority, true); 1830 + } 1826 1831 1827 1832 struct sk_buff *sock_wmalloc(struct sock *sk, unsigned long size, int force, 1828 1833 gfp_t priority);
+16 -8
net/core/sock.c
··· 2462 2462 } 2463 2463 2464 2464 /** 2465 - * sk_clone_lock - clone a socket, and lock its clone 2466 - * @sk: the socket to clone 2467 - * @priority: for allocation (%GFP_KERNEL, %GFP_ATOMIC, etc) 2465 + * sk_clone - clone a socket 2466 + * @sk: the socket to clone 2467 + * @priority: for allocation (%GFP_KERNEL, %GFP_ATOMIC, etc) 2468 + * @lock: if true, lock the cloned sk 2468 2469 * 2469 - * Caller must unlock socket even in error path (bh_unlock_sock(newsk)) 2470 + * If @lock is true, the clone is locked by bh_lock_sock(), and 2471 + * caller must unlock socket even in error path by bh_unlock_sock(). 2470 2472 */ 2471 - struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority) 2473 + struct sock *sk_clone(const struct sock *sk, const gfp_t priority, 2474 + bool lock) 2472 2475 { 2473 2476 struct proto *prot = READ_ONCE(sk->sk_prot); 2474 2477 struct sk_filter *filter; ··· 2500 2497 __netns_tracker_alloc(sock_net(newsk), &newsk->ns_tracker, 2501 2498 false, priority); 2502 2499 } 2500 + 2503 2501 sk_node_init(&newsk->sk_node); 2504 2502 sock_lock_init(newsk); 2505 - bh_lock_sock(newsk); 2503 + 2504 + if (lock) 2505 + bh_lock_sock(newsk); 2506 + 2506 2507 newsk->sk_backlog.head = newsk->sk_backlog.tail = NULL; 2507 2508 newsk->sk_backlog.len = 0; 2508 2509 ··· 2597 2590 * destructor and make plain sk_free() 2598 2591 */ 2599 2592 newsk->sk_destruct = NULL; 2600 - bh_unlock_sock(newsk); 2593 + if (lock) 2594 + bh_unlock_sock(newsk); 2601 2595 sk_free(newsk); 2602 2596 newsk = NULL; 2603 2597 goto out; 2604 2598 } 2605 - EXPORT_SYMBOL_GPL(sk_clone_lock); 2599 + EXPORT_SYMBOL_GPL(sk_clone); 2606 2600 2607 2601 static u32 sk_dst_gso_max_size(struct sock *sk, const struct net_device *dev) 2608 2602 {
+2 -3
net/ipv4/af_inet.c
··· 755 755 756 756 void __inet_accept(struct socket *sock, struct socket *newsock, struct sock *newsk) 757 757 { 758 - /* TODO: use sk_clone_lock() in SCTP and remove protocol checks */ 759 - if (mem_cgroup_sockets_enabled && 760 - (!IS_ENABLED(CONFIG_IP_SCTP) || sk_is_tcp(newsk))) { 758 + if (mem_cgroup_sockets_enabled) { 761 759 gfp_t gfp = GFP_KERNEL | __GFP_NOFAIL; 762 760 763 761 mem_cgroup_sk_alloc(newsk); ··· 788 790 789 791 newsock->state = SS_CONNECTED; 790 792 } 793 + EXPORT_SYMBOL_GPL(__inet_accept); 791 794 792 795 /* 793 796 * Accept a pending connection. The TCP layer now gives BSD semantics.
-51
net/sctp/ipv6.c
··· 777 777 return retval; 778 778 } 779 779 780 - /* Create and initialize a new sk for the socket to be returned by accept(). */ 781 - static struct sock *sctp_v6_create_accept_sk(struct sock *sk, 782 - struct sctp_association *asoc, 783 - bool kern) 784 - { 785 - struct ipv6_pinfo *newnp, *np = inet6_sk(sk); 786 - struct sctp6_sock *newsctp6sk; 787 - struct inet_sock *newinet; 788 - struct sock *newsk; 789 - 790 - newsk = sk_alloc(sock_net(sk), PF_INET6, GFP_KERNEL, sk->sk_prot, kern); 791 - if (!newsk) 792 - goto out; 793 - 794 - sock_init_data(NULL, newsk); 795 - 796 - sctp_copy_sock(newsk, sk, asoc); 797 - sock_reset_flag(sk, SOCK_ZAPPED); 798 - 799 - newsctp6sk = (struct sctp6_sock *)newsk; 800 - newinet = inet_sk(newsk); 801 - newinet->pinet6 = &newsctp6sk->inet6; 802 - newinet->ipv6_fl_list = NULL; 803 - 804 - sctp_sk(newsk)->v4mapped = sctp_sk(sk)->v4mapped; 805 - 806 - newnp = inet6_sk(newsk); 807 - 808 - memcpy(newnp, np, sizeof(struct ipv6_pinfo)); 809 - newnp->ipv6_mc_list = NULL; 810 - newnp->ipv6_ac_list = NULL; 811 - 812 - sctp_v6_copy_ip_options(sk, newsk); 813 - 814 - /* Initialize sk's sport, dport, rcv_saddr and daddr for getsockname() 815 - * and getpeername(). 816 - */ 817 - sctp_v6_to_sk_daddr(&asoc->peer.primary_addr, newsk); 818 - 819 - newsk->sk_v6_rcv_saddr = sk->sk_v6_rcv_saddr; 820 - 821 - if (newsk->sk_prot->init(newsk)) { 822 - sk_common_release(newsk); 823 - newsk = NULL; 824 - } 825 - 826 - out: 827 - return newsk; 828 - } 829 - 830 780 /* Format a sockaddr for return to user space. This makes sure the return is 831 781 * AF_INET or AF_INET6 depending on the SCTP_I_WANT_MAPPED_V4_ADDR option. 832 782 */ ··· 1123 1173 .bind_verify = sctp_inet6_bind_verify, 1124 1174 .send_verify = sctp_inet6_send_verify, 1125 1175 .supported_addrs = sctp_inet6_supported_addrs, 1126 - .create_accept_sk = sctp_v6_create_accept_sk, 1127 1176 .addr_to_user = sctp_v6_addr_to_user, 1128 1177 .to_sk_saddr = sctp_v6_to_sk_saddr, 1129 1178 .to_sk_daddr = sctp_v6_to_sk_daddr,
-33
net/sctp/protocol.c
··· 580 580 return INET_ECN_is_ce(ip_hdr(skb)->tos); 581 581 } 582 582 583 - /* Create and initialize a new sk for the socket returned by accept(). */ 584 - static struct sock *sctp_v4_create_accept_sk(struct sock *sk, 585 - struct sctp_association *asoc, 586 - bool kern) 587 - { 588 - struct sock *newsk = sk_alloc(sock_net(sk), PF_INET, GFP_KERNEL, 589 - sk->sk_prot, kern); 590 - struct inet_sock *newinet; 591 - 592 - if (!newsk) 593 - goto out; 594 - 595 - sock_init_data(NULL, newsk); 596 - 597 - sctp_copy_sock(newsk, sk, asoc); 598 - sock_reset_flag(newsk, SOCK_ZAPPED); 599 - 600 - sctp_v4_copy_ip_options(sk, newsk); 601 - 602 - newinet = inet_sk(newsk); 603 - 604 - newinet->inet_daddr = asoc->peer.primary_addr.v4.sin_addr.s_addr; 605 - 606 - if (newsk->sk_prot->init(newsk)) { 607 - sk_common_release(newsk); 608 - newsk = NULL; 609 - } 610 - 611 - out: 612 - return newsk; 613 - } 614 - 615 583 static int sctp_v4_addr_to_user(struct sctp_sock *sp, union sctp_addr *addr) 616 584 { 617 585 /* No address mapping for V4 sockets */ ··· 1087 1119 .bind_verify = sctp_inet_bind_verify, 1088 1120 .send_verify = sctp_inet_send_verify, 1089 1121 .supported_addrs = sctp_inet_supported_addrs, 1090 - .create_accept_sk = sctp_v4_create_accept_sk, 1091 1122 .addr_to_user = sctp_v4_addr_to_user, 1092 1123 .to_sk_saddr = sctp_v4_to_sk_saddr, 1093 1124 .to_sk_daddr = sctp_v4_to_sk_daddr,
+93 -116
net/sctp/socket.c
··· 1553 1553 spin_unlock_bh(&net->sctp.addr_wq_lock); 1554 1554 1555 1555 sock_put(sk); 1556 - 1557 - SCTP_DBG_OBJCNT_DEC(sock); 1558 1556 } 1559 1557 1560 1558 /* Handle EPIPE error. */ ··· 4842 4844 return 0; 4843 4845 } 4844 4846 4847 + static struct sock *sctp_clone_sock(struct sock *sk, 4848 + struct sctp_association *asoc, 4849 + enum sctp_socket_type type) 4850 + { 4851 + struct sock *newsk = sk_clone(sk, GFP_KERNEL, false); 4852 + struct inet_sock *newinet; 4853 + struct sctp_sock *newsp; 4854 + int err = -ENOMEM; 4855 + 4856 + if (!newsk) 4857 + return ERR_PTR(err); 4858 + 4859 + /* sk_clone() sets refcnt to 2 */ 4860 + sock_put(newsk); 4861 + 4862 + newinet = inet_sk(newsk); 4863 + newsp = sctp_sk(newsk); 4864 + 4865 + newsp->pf->to_sk_daddr(&asoc->peer.primary_addr, newsk); 4866 + newinet->inet_dport = htons(asoc->peer.port); 4867 + 4868 + newsp->pf->copy_ip_options(sk, newsk); 4869 + atomic_set(&newinet->inet_id, get_random_u16()); 4870 + 4871 + inet_set_bit(MC_LOOP, newsk); 4872 + newinet->mc_ttl = 1; 4873 + newinet->mc_index = 0; 4874 + newinet->mc_list = NULL; 4875 + 4876 + #if IS_ENABLED(CONFIG_IPV6) 4877 + if (sk->sk_family == AF_INET6) { 4878 + struct ipv6_pinfo *newnp = inet6_sk(newsk); 4879 + 4880 + newinet->pinet6 = &((struct sctp6_sock *)newsk)->inet6; 4881 + newinet->ipv6_fl_list = NULL; 4882 + 4883 + memcpy(newnp, inet6_sk(sk), sizeof(struct ipv6_pinfo)); 4884 + newnp->ipv6_mc_list = NULL; 4885 + newnp->ipv6_ac_list = NULL; 4886 + } 4887 + #endif 4888 + 4889 + skb_queue_head_init(&newsp->pd_lobby); 4890 + 4891 + newsp->ep = sctp_endpoint_new(newsk, GFP_KERNEL); 4892 + if (!newsp->ep) 4893 + goto out_release; 4894 + 4895 + SCTP_DBG_OBJCNT_INC(sock); 4896 + sk_sockets_allocated_inc(newsk); 4897 + sock_prot_inuse_add(sock_net(sk), newsk->sk_prot, 1); 4898 + 4899 + err = sctp_sock_migrate(sk, newsk, asoc, type); 4900 + if (err) 4901 + goto out_release; 4902 + 4903 + /* Set newsk security attributes from original sk and connection 4904 + * security attribute from asoc. 4905 + */ 4906 + security_sctp_sk_clone(asoc, sk, newsk); 4907 + 4908 + return newsk; 4909 + 4910 + out_release: 4911 + sk_common_release(newsk); 4912 + return ERR_PTR(err); 4913 + } 4914 + 4845 4915 /* 4.1.4 accept() - TCP Style Syntax 4846 4916 * 4847 4917 * Applications use accept() call to remove an established SCTP ··· 4919 4853 */ 4920 4854 static struct sock *sctp_accept(struct sock *sk, struct proto_accept_arg *arg) 4921 4855 { 4922 - struct sctp_sock *sp; 4923 - struct sctp_endpoint *ep; 4924 - struct sock *newsk = NULL; 4925 4856 struct sctp_association *asoc; 4926 - long timeo; 4857 + struct sock *newsk = NULL; 4927 4858 int error = 0; 4859 + long timeo; 4928 4860 4929 4861 lock_sock(sk); 4930 - 4931 - sp = sctp_sk(sk); 4932 - ep = sp->ep; 4933 4862 4934 4863 if (!sctp_style(sk, TCP)) { 4935 4864 error = -EOPNOTSUPP; ··· 4946 4885 /* We treat the list of associations on the endpoint as the accept 4947 4886 * queue and pick the first association on the list. 4948 4887 */ 4949 - asoc = list_entry(ep->asocs.next, struct sctp_association, asocs); 4888 + asoc = list_entry(sctp_sk(sk)->ep->asocs.next, 4889 + struct sctp_association, asocs); 4950 4890 4951 - newsk = sp->pf->create_accept_sk(sk, asoc, arg->kern); 4952 - if (!newsk) { 4953 - error = -ENOMEM; 4954 - goto out; 4955 - } 4956 - 4957 - /* Populate the fields of the newsk from the oldsk and migrate the 4958 - * asoc to the newsk. 4959 - */ 4960 - error = sctp_sock_migrate(sk, newsk, asoc, SCTP_SOCKET_TCP); 4961 - if (error) { 4962 - sk_common_release(newsk); 4891 + newsk = sctp_clone_sock(sk, asoc, SCTP_SOCKET_TCP); 4892 + if (IS_ERR(newsk)) { 4893 + error = PTR_ERR(newsk); 4963 4894 newsk = NULL; 4964 4895 } 4965 4896 ··· 5162 5109 sp->do_auto_asconf = 0; 5163 5110 list_del(&sp->auto_asconf_list); 5164 5111 } 5112 + 5165 5113 sctp_endpoint_free(sp->ep); 5114 + 5166 5115 sk_sockets_allocated_dec(sk); 5167 5116 sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1); 5117 + SCTP_DBG_OBJCNT_DEC(sock); 5168 5118 } 5169 5119 5170 5120 static void sctp_destruct_sock(struct sock *sk) ··· 5671 5615 5672 5616 /* Helper routine to branch off an association to a new socket. */ 5673 5617 static int sctp_do_peeloff(struct sock *sk, sctp_assoc_t id, 5674 - struct socket **sockp) 5618 + struct socket **sockp) 5675 5619 { 5676 5620 struct sctp_association *asoc = sctp_id2assoc(sk, id); 5677 - struct sctp_sock *sp = sctp_sk(sk); 5678 5621 struct socket *sock; 5622 + struct sock *newsk; 5679 5623 int err = 0; 5680 5624 5681 5625 /* Do not peel off from one netns to another one. */ ··· 5691 5635 if (!sctp_style(sk, UDP)) 5692 5636 return -EINVAL; 5693 5637 5694 - /* Create a new socket. */ 5695 - err = sock_create(sk->sk_family, SOCK_SEQPACKET, IPPROTO_SCTP, &sock); 5696 - if (err < 0) 5638 + err = sock_create_lite(sk->sk_family, SOCK_SEQPACKET, IPPROTO_SCTP, &sock); 5639 + if (err) 5697 5640 return err; 5698 5641 5699 - sctp_copy_sock(sock->sk, sk, asoc); 5700 - 5701 - /* Make peeled-off sockets more like 1-1 accepted sockets. 5702 - * Set the daddr and initialize id to something more random and also 5703 - * copy over any ip options. 5704 - */ 5705 - sp->pf->to_sk_daddr(&asoc->peer.primary_addr, sock->sk); 5706 - sp->pf->copy_ip_options(sk, sock->sk); 5707 - 5708 - /* Populate the fields of the newsk from the oldsk and migrate the 5709 - * asoc to the newsk. 5710 - */ 5711 - err = sctp_sock_migrate(sk, sock->sk, asoc, 5712 - SCTP_SOCKET_UDP_HIGH_BANDWIDTH); 5713 - if (err) { 5642 + newsk = sctp_clone_sock(sk, asoc, SCTP_SOCKET_UDP_HIGH_BANDWIDTH); 5643 + if (IS_ERR(newsk)) { 5714 5644 sock_release(sock); 5715 - sock = NULL; 5645 + *sockp = NULL; 5646 + return PTR_ERR(newsk); 5716 5647 } 5648 + 5649 + lock_sock_nested(newsk, SINGLE_DEPTH_NESTING); 5650 + __inet_accept(sk->sk_socket, sock, newsk); 5651 + release_sock(newsk); 5652 + 5653 + sock->ops = sk->sk_socket->ops; 5654 + __module_get(sock->ops->owner); 5717 5655 5718 5656 *sockp = sock; 5719 5657 ··· 9491 9441 sctp_skb_set_owner_r(skb, sk); 9492 9442 } 9493 9443 9494 - void sctp_copy_sock(struct sock *newsk, struct sock *sk, 9495 - struct sctp_association *asoc) 9496 - { 9497 - struct inet_sock *inet = inet_sk(sk); 9498 - struct inet_sock *newinet; 9499 - struct sctp_sock *sp = sctp_sk(sk); 9500 - 9501 - newsk->sk_type = sk->sk_type; 9502 - newsk->sk_bound_dev_if = sk->sk_bound_dev_if; 9503 - newsk->sk_flags = sk->sk_flags; 9504 - newsk->sk_tsflags = sk->sk_tsflags; 9505 - newsk->sk_no_check_tx = sk->sk_no_check_tx; 9506 - newsk->sk_no_check_rx = sk->sk_no_check_rx; 9507 - newsk->sk_reuse = sk->sk_reuse; 9508 - sctp_sk(newsk)->reuse = sp->reuse; 9509 - 9510 - newsk->sk_shutdown = sk->sk_shutdown; 9511 - newsk->sk_destruct = sk->sk_destruct; 9512 - newsk->sk_family = sk->sk_family; 9513 - newsk->sk_protocol = IPPROTO_SCTP; 9514 - newsk->sk_backlog_rcv = sk->sk_prot->backlog_rcv; 9515 - newsk->sk_sndbuf = sk->sk_sndbuf; 9516 - newsk->sk_rcvbuf = sk->sk_rcvbuf; 9517 - newsk->sk_lingertime = sk->sk_lingertime; 9518 - newsk->sk_rcvtimeo = READ_ONCE(sk->sk_rcvtimeo); 9519 - newsk->sk_sndtimeo = READ_ONCE(sk->sk_sndtimeo); 9520 - newsk->sk_rxhash = sk->sk_rxhash; 9521 - 9522 - newinet = inet_sk(newsk); 9523 - 9524 - /* Initialize sk's sport, dport, rcv_saddr and daddr for 9525 - * getsockname() and getpeername() 9526 - */ 9527 - newinet->inet_sport = inet->inet_sport; 9528 - newinet->inet_saddr = inet->inet_saddr; 9529 - newinet->inet_rcv_saddr = inet->inet_rcv_saddr; 9530 - newinet->inet_dport = htons(asoc->peer.port); 9531 - newinet->pmtudisc = inet->pmtudisc; 9532 - atomic_set(&newinet->inet_id, get_random_u16()); 9533 - 9534 - newinet->uc_ttl = inet->uc_ttl; 9535 - inet_set_bit(MC_LOOP, newsk); 9536 - newinet->mc_ttl = 1; 9537 - newinet->mc_index = 0; 9538 - newinet->mc_list = NULL; 9539 - 9540 - if (newsk->sk_flags & SK_FLAGS_TIMESTAMP) 9541 - net_enable_timestamp(); 9542 - 9543 - /* Set newsk security attributes from original sk and connection 9544 - * security attribute from asoc. 9545 - */ 9546 - security_sctp_sk_clone(asoc, sk, newsk); 9547 - } 9548 - 9549 - static inline void sctp_copy_descendant(struct sock *sk_to, 9550 - const struct sock *sk_from) 9551 - { 9552 - size_t ancestor_size = sizeof(struct inet_sock); 9553 - 9554 - ancestor_size += sk_from->sk_prot->obj_size; 9555 - ancestor_size -= offsetof(struct sctp_sock, pd_lobby); 9556 - __inet_sk_copy_descendant(sk_to, sk_from, ancestor_size); 9557 - } 9558 - 9559 9444 /* Populate the fields of the newsk from the oldsk and migrate the assoc 9560 9445 * and its messages to the newsk. 9561 9446 */ ··· 9506 9521 struct sctp_ulpevent *event; 9507 9522 struct sctp_bind_hashbucket *head; 9508 9523 int err; 9509 - 9510 - /* Migrate socket buffer sizes and all the socket level options to the 9511 - * new socket. 9512 - */ 9513 - newsk->sk_sndbuf = oldsk->sk_sndbuf; 9514 - newsk->sk_rcvbuf = oldsk->sk_rcvbuf; 9515 - /* Brute force copy old sctp opt. */ 9516 - sctp_copy_descendant(newsk, oldsk); 9517 9524 9518 9525 /* Restore the ep value that was overwritten with the above structure 9519 9526 * copy.