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: d021c34405
("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>
This commit is contained in:
parent
fde9cd69a5
commit
a915b982d8
|
@ -263,6 +263,31 @@ vmci_transport_send_control_pkt_bh(struct sockaddr_vm *src,
|
||||||
false);
|
false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
vmci_transport_alloc_send_control_pkt(struct sockaddr_vm *src,
|
||||||
|
struct sockaddr_vm *dst,
|
||||||
|
enum vmci_transport_packet_type type,
|
||||||
|
u64 size,
|
||||||
|
u64 mode,
|
||||||
|
struct vmci_transport_waiting_info *wait,
|
||||||
|
u16 proto,
|
||||||
|
struct vmci_handle handle)
|
||||||
|
{
|
||||||
|
struct vmci_transport_packet *pkt;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
pkt = kmalloc(sizeof(*pkt), GFP_KERNEL);
|
||||||
|
if (!pkt)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
err = __vmci_transport_send_control_pkt(pkt, src, dst, type, size,
|
||||||
|
mode, wait, proto, handle,
|
||||||
|
true);
|
||||||
|
kfree(pkt);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
vmci_transport_send_control_pkt(struct sock *sk,
|
vmci_transport_send_control_pkt(struct sock *sk,
|
||||||
enum vmci_transport_packet_type type,
|
enum vmci_transport_packet_type type,
|
||||||
|
@ -272,9 +297,7 @@ vmci_transport_send_control_pkt(struct sock *sk,
|
||||||
u16 proto,
|
u16 proto,
|
||||||
struct vmci_handle handle)
|
struct vmci_handle handle)
|
||||||
{
|
{
|
||||||
struct vmci_transport_packet *pkt;
|
|
||||||
struct vsock_sock *vsk;
|
struct vsock_sock *vsk;
|
||||||
int err;
|
|
||||||
|
|
||||||
vsk = vsock_sk(sk);
|
vsk = vsock_sk(sk);
|
||||||
|
|
||||||
|
@ -284,17 +307,10 @@ vmci_transport_send_control_pkt(struct sock *sk,
|
||||||
if (!vsock_addr_bound(&vsk->remote_addr))
|
if (!vsock_addr_bound(&vsk->remote_addr))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
pkt = kmalloc(sizeof(*pkt), GFP_KERNEL);
|
return vmci_transport_alloc_send_control_pkt(&vsk->local_addr,
|
||||||
if (!pkt)
|
&vsk->remote_addr,
|
||||||
return -ENOMEM;
|
type, size, mode,
|
||||||
|
wait, proto, handle);
|
||||||
err = __vmci_transport_send_control_pkt(pkt, &vsk->local_addr,
|
|
||||||
&vsk->remote_addr, type, size,
|
|
||||||
mode, wait, proto, handle,
|
|
||||||
true);
|
|
||||||
kfree(pkt);
|
|
||||||
|
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int vmci_transport_send_reset_bh(struct sockaddr_vm *dst,
|
static 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,
|
||||||
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,
|
|
||||||
VMCI_TRANSPORT_PACKET_TYPE_RST,
|
vsk = vsock_sk(sk);
|
||||||
0, 0, NULL, VSOCK_PROTO_INVALID,
|
|
||||||
VMCI_INVALID_HANDLE);
|
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,
|
||||||
|
0, 0, NULL, VSOCK_PROTO_INVALID,
|
||||||
|
VMCI_INVALID_HANDLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int vmci_transport_send_negotiate(struct sock *sk, size_t size)
|
static int vmci_transport_send_negotiate(struct sock *sk, size_t size)
|
||||||
|
|
Loading…
Reference in New Issue