aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJorgen Hansen <jhansen@vmware.com>2018-12-18 03:34:06 -0500
committerDavid S. Miller <davem@davemloft.net>2018-12-18 14:53:42 -0500
commita915b982d8f5e4295f64b8dd37ce753874867e88 (patch)
tree0c16321ceef6295f5b8e7215860679388e879a7b /net
parentfde9cd69a59f7ee405c87fff84bc08fa2a550e47 (diff)
VSOCK: Send reset control packet when socket is partially bound
If a server side socket is bound to an address, but not in the listening state yet, incoming connection requests should receive a reset control packet in response. However, the function used to send the reset silently drops the reset packet if the sending socket isn't bound to a remote address (as is the case for a bound socket not yet in the listening state). This change fixes this by using the src of the incoming packet as destination for the reset packet in this case. Fixes: d021c344051a ("VSOCK: Introduce VM Sockets") Reviewed-by: Adit Ranadive <aditr@vmware.com> Reviewed-by: Vishnu Dasa <vdasa@vmware.com> Signed-off-by: Jorgen Hansen <jhansen@vmware.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/vmw_vsock/vmci_transport.c67
1 files changed, 50 insertions, 17 deletions
diff --git a/net/vmw_vsock/vmci_transport.c b/net/vmw_vsock/vmci_transport.c
index cb332adb84cd..c361ce782412 100644
--- a/net/vmw_vsock/vmci_transport.c
+++ b/net/vmw_vsock/vmci_transport.c
@@ -264,6 +264,31 @@ vmci_transport_send_control_pkt_bh(struct sockaddr_vm *src,
264} 264}
265 265
266static int 266static int
267vmci_transport_alloc_send_control_pkt(struct sockaddr_vm *src,
268 struct sockaddr_vm *dst,
269 enum vmci_transport_packet_type type,
270 u64 size,
271 u64 mode,
272 struct vmci_transport_waiting_info *wait,
273 u16 proto,
274 struct vmci_handle handle)
275{
276 struct vmci_transport_packet *pkt;
277 int err;
278
279 pkt = kmalloc(sizeof(*pkt), GFP_KERNEL);
280 if (!pkt)
281 return -ENOMEM;
282
283 err = __vmci_transport_send_control_pkt(pkt, src, dst, type, size,
284 mode, wait, proto, handle,
285 true);
286 kfree(pkt);
287
288 return err;
289}
290
291static int
267vmci_transport_send_control_pkt(struct sock *sk, 292vmci_transport_send_control_pkt(struct sock *sk,
268 enum vmci_transport_packet_type type, 293 enum vmci_transport_packet_type type,
269 u64 size, 294 u64 size,
@@ -272,9 +297,7 @@ vmci_transport_send_control_pkt(struct sock *sk,
272 u16 proto, 297 u16 proto,
273 struct vmci_handle handle) 298 struct vmci_handle handle)
274{ 299{
275 struct vmci_transport_packet *pkt;
276 struct vsock_sock *vsk; 300 struct vsock_sock *vsk;
277 int err;
278 301
279 vsk = vsock_sk(sk); 302 vsk = vsock_sk(sk);
280 303
@@ -284,17 +307,10 @@ vmci_transport_send_control_pkt(struct sock *sk,
284 if (!vsock_addr_bound(&vsk->remote_addr)) 307 if (!vsock_addr_bound(&vsk->remote_addr))
285 return -EINVAL; 308 return -EINVAL;
286 309
287 pkt = kmalloc(sizeof(*pkt), GFP_KERNEL); 310 return vmci_transport_alloc_send_control_pkt(&vsk->local_addr,
288 if (!pkt) 311 &vsk->remote_addr,
289 return -ENOMEM; 312 type, size, mode,
290 313 wait, proto, handle);
291 err = __vmci_transport_send_control_pkt(pkt, &vsk->local_addr,
292 &vsk->remote_addr, type, size,
293 mode, wait, proto, handle,
294 true);
295 kfree(pkt);
296
297 return err;
298} 314}
299 315
300static int vmci_transport_send_reset_bh(struct sockaddr_vm *dst, 316static int vmci_transport_send_reset_bh(struct sockaddr_vm *dst,
@@ -312,12 +328,29 @@ static int vmci_transport_send_reset_bh(struct sockaddr_vm *dst,
312static int vmci_transport_send_reset(struct sock *sk, 328static int vmci_transport_send_reset(struct sock *sk,
313 struct vmci_transport_packet *pkt) 329 struct vmci_transport_packet *pkt)
314{ 330{
331 struct sockaddr_vm *dst_ptr;
332 struct sockaddr_vm dst;
333 struct vsock_sock *vsk;
334
315 if (pkt->type == VMCI_TRANSPORT_PACKET_TYPE_RST) 335 if (pkt->type == VMCI_TRANSPORT_PACKET_TYPE_RST)
316 return 0; 336 return 0;
317 return vmci_transport_send_control_pkt(sk, 337
318 VMCI_TRANSPORT_PACKET_TYPE_RST, 338 vsk = vsock_sk(sk);
319 0, 0, NULL, VSOCK_PROTO_INVALID, 339
320 VMCI_INVALID_HANDLE); 340 if (!vsock_addr_bound(&vsk->local_addr))
341 return -EINVAL;
342
343 if (vsock_addr_bound(&vsk->remote_addr)) {
344 dst_ptr = &vsk->remote_addr;
345 } else {
346 vsock_addr_init(&dst, pkt->dg.src.context,
347 pkt->src_port);
348 dst_ptr = &dst;
349 }
350 return vmci_transport_alloc_send_control_pkt(&vsk->local_addr, dst_ptr,
351 VMCI_TRANSPORT_PACKET_TYPE_RST,
352 0, 0, NULL, VSOCK_PROTO_INVALID,
353 VMCI_INVALID_HANDLE);
321} 354}
322 355
323static int vmci_transport_send_negotiate(struct sock *sk, size_t size) 356static int vmci_transport_send_negotiate(struct sock *sk, size_t size)