Commit a915b982 authored by Jorgen Hansen's avatar Jorgen Hansen Committed by David S. Miller

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: d021c344 ("VSOCK: Introduce VM Sockets")
Reviewed-by: default avatarAdit Ranadive <aditr@vmware.com>
Reviewed-by: default avatarVishnu Dasa <vdasa@vmware.com>
Signed-off-by: default avatarJorgen Hansen <jhansen@vmware.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent fde9cd69
...@@ -264,7 +264,8 @@ vmci_transport_send_control_pkt_bh(struct sockaddr_vm *src, ...@@ -264,7 +264,8 @@ vmci_transport_send_control_pkt_bh(struct sockaddr_vm *src,
} }
static int static int
vmci_transport_send_control_pkt(struct sock *sk, vmci_transport_alloc_send_control_pkt(struct sockaddr_vm *src,
struct sockaddr_vm *dst,
enum vmci_transport_packet_type type, enum vmci_transport_packet_type type,
u64 size, u64 size,
u64 mode, u64 mode,
...@@ -273,23 +274,13 @@ vmci_transport_send_control_pkt(struct sock *sk, ...@@ -273,23 +274,13 @@ vmci_transport_send_control_pkt(struct sock *sk,
struct vmci_handle handle) struct vmci_handle handle)
{ {
struct vmci_transport_packet *pkt; struct vmci_transport_packet *pkt;
struct vsock_sock *vsk;
int err; int err;
vsk = vsock_sk(sk);
if (!vsock_addr_bound(&vsk->local_addr))
return -EINVAL;
if (!vsock_addr_bound(&vsk->remote_addr))
return -EINVAL;
pkt = kmalloc(sizeof(*pkt), GFP_KERNEL); pkt = kmalloc(sizeof(*pkt), GFP_KERNEL);
if (!pkt) if (!pkt)
return -ENOMEM; return -ENOMEM;
err = __vmci_transport_send_control_pkt(pkt, &vsk->local_addr, err = __vmci_transport_send_control_pkt(pkt, src, dst, type, size,
&vsk->remote_addr, type, size,
mode, wait, proto, handle, mode, wait, proto, handle,
true); true);
kfree(pkt); kfree(pkt);
...@@ -297,6 +288,31 @@ vmci_transport_send_control_pkt(struct sock *sk, ...@@ -297,6 +288,31 @@ vmci_transport_send_control_pkt(struct sock *sk,
return err; return err;
} }
static int
vmci_transport_send_control_pkt(struct sock *sk,
enum vmci_transport_packet_type type,
u64 size,
u64 mode,
struct vmci_transport_waiting_info *wait,
u16 proto,
struct vmci_handle handle)
{
struct vsock_sock *vsk;
vsk = vsock_sk(sk);
if (!vsock_addr_bound(&vsk->local_addr))
return -EINVAL;
if (!vsock_addr_bound(&vsk->remote_addr))
return -EINVAL;
return vmci_transport_alloc_send_control_pkt(&vsk->local_addr,
&vsk->remote_addr,
type, size, mode,
wait, proto, handle);
}
static int vmci_transport_send_reset_bh(struct sockaddr_vm *dst, static int vmci_transport_send_reset_bh(struct sockaddr_vm *dst,
struct sockaddr_vm *src, struct sockaddr_vm *src,
struct vmci_transport_packet *pkt) struct vmci_transport_packet *pkt)
...@@ -312,9 +328,26 @@ static int vmci_transport_send_reset_bh(struct sockaddr_vm *dst, ...@@ -312,9 +328,26 @@ static int vmci_transport_send_reset_bh(struct sockaddr_vm *dst,
static int vmci_transport_send_reset(struct sock *sk, static int vmci_transport_send_reset(struct sock *sk,
struct vmci_transport_packet *pkt) struct vmci_transport_packet *pkt)
{ {
struct sockaddr_vm *dst_ptr;
struct sockaddr_vm dst;
struct vsock_sock *vsk;
if (pkt->type == VMCI_TRANSPORT_PACKET_TYPE_RST) if (pkt->type == VMCI_TRANSPORT_PACKET_TYPE_RST)
return 0; return 0;
return vmci_transport_send_control_pkt(sk,
vsk = vsock_sk(sk);
if (!vsock_addr_bound(&vsk->local_addr))
return -EINVAL;
if (vsock_addr_bound(&vsk->remote_addr)) {
dst_ptr = &vsk->remote_addr;
} else {
vsock_addr_init(&dst, pkt->dg.src.context,
pkt->src_port);
dst_ptr = &dst;
}
return vmci_transport_alloc_send_control_pkt(&vsk->local_addr, dst_ptr,
VMCI_TRANSPORT_PACKET_TYPE_RST, VMCI_TRANSPORT_PACKET_TYPE_RST,
0, 0, NULL, VSOCK_PROTO_INVALID, 0, 0, NULL, VSOCK_PROTO_INVALID,
VMCI_INVALID_HANDLE); VMCI_INVALID_HANDLE);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment