[SCTP]: Fix the bind_addr info during migration.

During accept/migrate the code attempts to copy the addresses from
the parent endpoint to the new endpoint. However, if the parent
was bound to a wildcard address, then we end up pointlessly copying
all of the current addresses on the system.

Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by Vlad Yasevich and committed by David S. Miller 8e71a11c f26f7c48

+31 -10
+3
include/net/sctp/structs.h
··· 1184 const struct sctp_bind_addr *src, 1185 sctp_scope_t scope, gfp_t gfp, 1186 int flags); 1187 int sctp_add_bind_addr(struct sctp_bind_addr *, union sctp_addr *, 1188 __u8 use_as_src, gfp_t gfp); 1189 int sctp_del_bind_addr(struct sctp_bind_addr *, union sctp_addr *);
··· 1184 const struct sctp_bind_addr *src, 1185 sctp_scope_t scope, gfp_t gfp, 1186 int flags); 1187 + int sctp_bind_addr_dup(struct sctp_bind_addr *dest, 1188 + const struct sctp_bind_addr *src, 1189 + gfp_t gfp); 1190 int sctp_add_bind_addr(struct sctp_bind_addr *, union sctp_addr *, 1191 __u8 use_as_src, gfp_t gfp); 1192 int sctp_del_bind_addr(struct sctp_bind_addr *, union sctp_addr *);
+26
net/sctp/bind_addr.c
··· 105 return error; 106 } 107 108 /* Initialize the SCTP_bind_addr structure for either an endpoint or 109 * an association. 110 */
··· 105 return error; 106 } 107 108 + /* Exactly duplicate the address lists. This is necessary when doing 109 + * peer-offs and accepts. We don't want to put all the current system 110 + * addresses into the endpoint. That's useless. But we do want duplicat 111 + * the list of bound addresses that the older endpoint used. 112 + */ 113 + int sctp_bind_addr_dup(struct sctp_bind_addr *dest, 114 + const struct sctp_bind_addr *src, 115 + gfp_t gfp) 116 + { 117 + struct sctp_sockaddr_entry *addr; 118 + struct list_head *pos; 119 + int error = 0; 120 + 121 + /* All addresses share the same port. */ 122 + dest->port = src->port; 123 + 124 + list_for_each(pos, &src->address_list) { 125 + addr = list_entry(pos, struct sctp_sockaddr_entry, list); 126 + error = sctp_add_bind_addr(dest, &addr->a, 1, gfp); 127 + if (error < 0) 128 + break; 129 + } 130 + 131 + return error; 132 + } 133 + 134 /* Initialize the SCTP_bind_addr structure for either an endpoint or 135 * an association. 136 */
+2 -10
net/sctp/socket.c
··· 6326 struct sk_buff *skb, *tmp; 6327 struct sctp_ulpevent *event; 6328 struct sctp_bind_hashbucket *head; 6329 - int flags = 0; 6330 6331 /* Migrate socket buffer sizes and all the socket level options to the 6332 * new socket. ··· 6355 /* Copy the bind_addr list from the original endpoint to the new 6356 * endpoint so that we can handle restarts properly 6357 */ 6358 - if (PF_INET6 == assoc->base.sk->sk_family) 6359 - flags = SCTP_ADDR6_ALLOWED; 6360 - if (assoc->peer.ipv4_address) 6361 - flags |= SCTP_ADDR4_PEERSUPP; 6362 - if (assoc->peer.ipv6_address) 6363 - flags |= SCTP_ADDR6_PEERSUPP; 6364 - sctp_bind_addr_copy(&newsp->ep->base.bind_addr, 6365 - &oldsp->ep->base.bind_addr, 6366 - SCTP_SCOPE_GLOBAL, GFP_KERNEL, flags); 6367 6368 /* Move any messages in the old socket's receive queue that are for the 6369 * peeled off association to the new socket's receive queue.
··· 6326 struct sk_buff *skb, *tmp; 6327 struct sctp_ulpevent *event; 6328 struct sctp_bind_hashbucket *head; 6329 6330 /* Migrate socket buffer sizes and all the socket level options to the 6331 * new socket. ··· 6356 /* Copy the bind_addr list from the original endpoint to the new 6357 * endpoint so that we can handle restarts properly 6358 */ 6359 + sctp_bind_addr_dup(&newsp->ep->base.bind_addr, 6360 + &oldsp->ep->base.bind_addr, GFP_KERNEL); 6361 6362 /* Move any messages in the old socket's receive queue that are for the 6363 * peeled off association to the new socket's receive queue.