Stefano Garzarella
2021-Jan-29 11:03 UTC
[RFC PATCH v3 10/13] virtio/vsock: rest of SOCK_SEQPACKET support
On Mon, Jan 25, 2021 at 02:15:26PM +0300, Arseny Krasnov wrote:>This adds rest of logic for SEQPACKET: >1) Shared functions for packet sending now set valid type of packet > according socket type. >2) SEQPACKET specific function like SEQ_BEGIN send and data dequeue. >3) TAP support for SEQPACKET is not so easy if it is necessary to >send whole record to TAP interface. This could be done by allocating >new packet when whole record is received, data of record must be >copied to TAP packet. > >Signed-off-by: Arseny Krasnov <arseny.krasnov at kaspersky.com> >--- > include/linux/virtio_vsock.h | 7 ++++ > net/vmw_vsock/virtio_transport_common.c | 55 +++++++++++++++++++++---- > 2 files changed, 55 insertions(+), 7 deletions(-) > >diff --git a/include/linux/virtio_vsock.h b/include/linux/virtio_vsock.h >index af8705ea8b95..ad9783df97c9 100644 >--- a/include/linux/virtio_vsock.h >+++ b/include/linux/virtio_vsock.h >@@ -84,7 +84,14 @@ virtio_transport_dgram_dequeue(struct vsock_sock *vsk, > struct msghdr *msg, > size_t len, int flags); > >+bool virtio_transport_seqpacket_seq_send_len(struct vsock_sock *vsk, size_t len); > size_t virtio_transport_seqpacket_seq_get_len(struct vsock_sock *vsk); >+ssize_t >+virtio_transport_seqpacket_dequeue(struct vsock_sock *vsk, >+ struct msghdr *msg, >+ size_t len, >+ int type); >+ > s64 virtio_transport_stream_has_data(struct vsock_sock *vsk); > s64 virtio_transport_stream_has_space(struct vsock_sock *vsk); > >diff --git a/net/vmw_vsock/virtio_transport_common.c b/net/vmw_vsock/virtio_transport_common.c >index 90f9feef9d8f..fab14679ca7b 100644 >--- a/net/vmw_vsock/virtio_transport_common.c >+++ b/net/vmw_vsock/virtio_transport_common.c >@@ -139,6 +139,7 @@ static struct sk_buff *virtio_transport_build_skb(void *opaque) > break; > case VIRTIO_VSOCK_OP_CREDIT_UPDATE: > case VIRTIO_VSOCK_OP_CREDIT_REQUEST: >+ case VIRTIO_VSOCK_OP_SEQ_BEGIN: > hdr->op = cpu_to_le16(AF_VSOCK_OP_CONTROL); > break; > default: >@@ -157,6 +158,10 @@ static struct sk_buff *virtio_transport_build_skb(void *opaque) > > void virtio_transport_deliver_tap_pkt(struct virtio_vsock_pkt *pkt) > { >+ /* TODO: implement tap support for SOCK_SEQPACKET. */I think we should do this before merging SOCK_SEQPACKET support because it can be very useful to use tcpdump to figure out what's going on, do you think it's complicated?>+ if (le16_to_cpu(pkt->hdr.type) == VIRTIO_VSOCK_TYPE_SEQPACKET) >+ return; >+ > if (pkt->tap_delivered) > return; > >@@ -405,6 +410,19 @@ static u16 virtio_transport_get_type(struct sock *sk) > return VIRTIO_VSOCK_TYPE_SEQPACKET; > } > >+bool virtio_transport_seqpacket_seq_send_len(struct vsock_sock *vsk, size_t len) >+{ >+ struct virtio_vsock_pkt_info info = { >+ .type = VIRTIO_VSOCK_TYPE_SEQPACKET, >+ .op = VIRTIO_VSOCK_OP_SEQ_BEGIN, >+ .vsk = vsk, >+ .flags = len >+ }; >+ >+ return virtio_transport_send_pkt_info(vsk, &info); >+} >+EXPORT_SYMBOL_GPL(virtio_transport_seqpacket_seq_send_len); >+ > static inline void virtio_transport_del_n_free_pkt(struct virtio_vsock_pkt *pkt) > { > list_del(&pkt->list); >@@ -576,6 +594,18 @@ virtio_transport_stream_dequeue(struct vsock_sock *vsk, > } > EXPORT_SYMBOL_GPL(virtio_transport_stream_dequeue); > >+ssize_t >+virtio_transport_seqpacket_dequeue(struct vsock_sock *vsk, >+ struct msghdr *msg, >+ size_t len, int flags) >+{ >+ if (flags & MSG_PEEK) >+ return -EOPNOTSUPP; >+ >+ return virtio_transport_seqpacket_do_dequeue(vsk, msg, len); >+} >+EXPORT_SYMBOL_GPL(virtio_transport_seqpacket_dequeue); >+ > int > virtio_transport_dgram_dequeue(struct vsock_sock *vsk, > struct msghdr *msg, >@@ -659,14 +689,15 @@ EXPORT_SYMBOL_GPL(virtio_transport_do_socket_init); > void virtio_transport_notify_buffer_size(struct vsock_sock *vsk, u64 *val) > { > struct virtio_vsock_sock *vvs = vsk->trans; >+ int type; > > if (*val > VIRTIO_VSOCK_MAX_BUF_SIZE) > *val = VIRTIO_VSOCK_MAX_BUF_SIZE; > > vvs->buf_alloc = *val; > >- virtio_transport_send_credit_update(vsk, VIRTIO_VSOCK_TYPE_STREAM, >- NULL); >+ type = virtio_transport_get_type(sk_vsock(vsk));How about setting the type in virtio_transport_send_pkt_info(), so we can avoid all these changes?>+ virtio_transport_send_credit_update(vsk, type, NULL); > } > EXPORT_SYMBOL_GPL(virtio_transport_notify_buffer_size); > >@@ -793,10 +824,11 @@ int virtio_transport_connect(struct vsock_sock *vsk) > { > struct virtio_vsock_pkt_info info = { > .op = VIRTIO_VSOCK_OP_REQUEST, >- .type = VIRTIO_VSOCK_TYPE_STREAM, > .vsk = vsk, > }; > >+ info.type = virtio_transport_get_type(sk_vsock(vsk)); >+ > return virtio_transport_send_pkt_info(vsk, &info); > } > EXPORT_SYMBOL_GPL(virtio_transport_connect); >@@ -805,7 +837,6 @@ int virtio_transport_shutdown(struct vsock_sock *vsk, int mode) > { > struct virtio_vsock_pkt_info info = { > .op = VIRTIO_VSOCK_OP_SHUTDOWN, >- .type = VIRTIO_VSOCK_TYPE_STREAM, > .flags = (mode & RCV_SHUTDOWN ? > VIRTIO_VSOCK_SHUTDOWN_RCV : 0) | > (mode & SEND_SHUTDOWN ? >@@ -813,6 +844,8 @@ int virtio_transport_shutdown(struct vsock_sock *vsk, int mode) > .vsk = vsk, > }; > >+ info.type = virtio_transport_get_type(sk_vsock(vsk)); >+ > return virtio_transport_send_pkt_info(vsk, &info); > } > EXPORT_SYMBOL_GPL(virtio_transport_shutdown); >@@ -834,12 +867,18 @@ virtio_transport_stream_enqueue(struct vsock_sock *vsk, > { > struct virtio_vsock_pkt_info info = { > .op = VIRTIO_VSOCK_OP_RW, >- .type = VIRTIO_VSOCK_TYPE_STREAM, > .msg = msg, > .pkt_len = len, > .vsk = vsk, >+ .flags = 0, > }; > >+ info.type = virtio_transport_get_type(sk_vsock(vsk)); >+ >+ if (info.type == VIRTIO_VSOCK_TYPE_SEQPACKET && >+ msg->msg_flags & MSG_EOR) >+ info.flags |= VIRTIO_VSOCK_RW_EOR; >+ > return virtio_transport_send_pkt_info(vsk, &info); > } > EXPORT_SYMBOL_GPL(virtio_transport_stream_enqueue); >@@ -857,7 +896,6 @@ static int virtio_transport_reset(struct vsock_sock *vsk, > { > struct virtio_vsock_pkt_info info = { > .op = VIRTIO_VSOCK_OP_RST, >- .type = VIRTIO_VSOCK_TYPE_STREAM, > .reply = !!pkt, > .vsk = vsk, > }; >@@ -866,6 +904,8 @@ static int virtio_transport_reset(struct vsock_sock *vsk, > if (pkt && le16_to_cpu(pkt->hdr.op) == VIRTIO_VSOCK_OP_RST) > return 0; > >+ info.type = virtio_transport_get_type(sk_vsock(vsk)); >+ > return virtio_transport_send_pkt_info(vsk, &info); > } > >@@ -1177,13 +1217,14 @@ virtio_transport_send_response(struct vsock_sock *vsk, > { > struct virtio_vsock_pkt_info info = { > .op = VIRTIO_VSOCK_OP_RESPONSE, >- .type = VIRTIO_VSOCK_TYPE_STREAM, > .remote_cid = le64_to_cpu(pkt->hdr.src_cid), > .remote_port = le32_to_cpu(pkt->hdr.src_port), > .reply = true, > .vsk = vsk, > }; > >+ info.type = virtio_transport_get_type(sk_vsock(vsk)); >+ > return virtio_transport_send_pkt_info(vsk, &info); > } > >-- >2.25.1 >