Skip to content

Commit 634f1a7

Browse files
Bobby Eshlemandavem330
Bobby Eshleman
authored andcommitted
vsock: support sockmap
This patch adds sockmap support for vsock sockets. It is intended to be usable by all transports, but only the virtio and loopback transports are implemented. SOCK_STREAM, SOCK_DGRAM, and SOCK_SEQPACKET are all supported. Signed-off-by: Bobby Eshleman <[email protected]> Acked-by: Michael S. Tsirkin <[email protected]> Reviewed-by: Stefano Garzarella <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 24265c2 commit 634f1a7

File tree

9 files changed

+281
-6
lines changed

9 files changed

+281
-6
lines changed

Diff for: drivers/vhost/vsock.c

+1
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,7 @@ static struct virtio_transport vhost_transport = {
439439
.notify_send_post_enqueue = virtio_transport_notify_send_post_enqueue,
440440
.notify_buffer_size = virtio_transport_notify_buffer_size,
441441

442+
.read_skb = virtio_transport_read_skb,
442443
},
443444

444445
.send_pkt = vhost_transport_send_pkt,

Diff for: include/linux/virtio_vsock.h

+1
Original file line numberDiff line numberDiff line change
@@ -245,4 +245,5 @@ u32 virtio_transport_get_credit(struct virtio_vsock_sock *vvs, u32 wanted);
245245
void virtio_transport_put_credit(struct virtio_vsock_sock *vvs, u32 credit);
246246
void virtio_transport_deliver_tap_pkt(struct sk_buff *skb);
247247
int virtio_transport_purge_skbs(void *vsk, struct sk_buff_head *list);
248+
int virtio_transport_read_skb(struct vsock_sock *vsk, skb_read_actor_t read_actor);
248249
#endif /* _LINUX_VIRTIO_VSOCK_H */

Diff for: include/net/af_vsock.h

+17
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ struct vsock_sock {
7575
void *trans;
7676
};
7777

78+
s64 vsock_connectible_has_data(struct vsock_sock *vsk);
7879
s64 vsock_stream_has_data(struct vsock_sock *vsk);
7980
s64 vsock_stream_has_space(struct vsock_sock *vsk);
8081
struct sock *vsock_create_connected(struct sock *parent);
@@ -173,6 +174,9 @@ struct vsock_transport {
173174

174175
/* Addressing. */
175176
u32 (*get_local_cid)(void);
177+
178+
/* Read a single skb */
179+
int (*read_skb)(struct vsock_sock *, skb_read_actor_t);
176180
};
177181

178182
/**** CORE ****/
@@ -225,5 +229,18 @@ int vsock_init_tap(void);
225229
int vsock_add_tap(struct vsock_tap *vt);
226230
int vsock_remove_tap(struct vsock_tap *vt);
227231
void vsock_deliver_tap(struct sk_buff *build_skb(void *opaque), void *opaque);
232+
int vsock_connectible_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
233+
int flags);
234+
int vsock_dgram_recvmsg(struct socket *sock, struct msghdr *msg,
235+
size_t len, int flags);
236+
237+
#ifdef CONFIG_BPF_SYSCALL
238+
extern struct proto vsock_proto;
239+
int vsock_bpf_update_proto(struct sock *sk, struct sk_psock *psock, bool restore);
240+
void __init vsock_bpf_build_proto(void);
241+
#else
242+
static inline void __init vsock_bpf_build_proto(void)
243+
{}
244+
#endif
228245

229246
#endif /* __AF_VSOCK_H__ */

Diff for: net/vmw_vsock/Makefile

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ obj-$(CONFIG_HYPERV_VSOCKETS) += hv_sock.o
88
obj-$(CONFIG_VSOCKETS_LOOPBACK) += vsock_loopback.o
99

1010
vsock-y += af_vsock.o af_vsock_tap.o vsock_addr.o
11+
vsock-$(CONFIG_BPF_SYSCALL) += vsock_bpf.o
1112

1213
vsock_diag-y += diag.o
1314

Diff for: net/vmw_vsock/af_vsock.c

+58-6
Original file line numberDiff line numberDiff line change
@@ -116,10 +116,13 @@ static void vsock_sk_destruct(struct sock *sk);
116116
static int vsock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb);
117117

118118
/* Protocol family. */
119-
static struct proto vsock_proto = {
119+
struct proto vsock_proto = {
120120
.name = "AF_VSOCK",
121121
.owner = THIS_MODULE,
122122
.obj_size = sizeof(struct vsock_sock),
123+
#ifdef CONFIG_BPF_SYSCALL
124+
.psock_update_sk_prot = vsock_bpf_update_proto,
125+
#endif
123126
};
124127

125128
/* The default peer timeout indicates how long we will wait for a peer response
@@ -865,7 +868,7 @@ s64 vsock_stream_has_data(struct vsock_sock *vsk)
865868
}
866869
EXPORT_SYMBOL_GPL(vsock_stream_has_data);
867870

868-
static s64 vsock_connectible_has_data(struct vsock_sock *vsk)
871+
s64 vsock_connectible_has_data(struct vsock_sock *vsk)
869872
{
870873
struct sock *sk = sk_vsock(vsk);
871874

@@ -874,6 +877,7 @@ static s64 vsock_connectible_has_data(struct vsock_sock *vsk)
874877
else
875878
return vsock_stream_has_data(vsk);
876879
}
880+
EXPORT_SYMBOL_GPL(vsock_connectible_has_data);
877881

878882
s64 vsock_stream_has_space(struct vsock_sock *vsk)
879883
{
@@ -1131,6 +1135,13 @@ static __poll_t vsock_poll(struct file *file, struct socket *sock,
11311135
return mask;
11321136
}
11331137

1138+
static int vsock_read_skb(struct sock *sk, skb_read_actor_t read_actor)
1139+
{
1140+
struct vsock_sock *vsk = vsock_sk(sk);
1141+
1142+
return vsk->transport->read_skb(vsk, read_actor);
1143+
}
1144+
11341145
static int vsock_dgram_sendmsg(struct socket *sock, struct msghdr *msg,
11351146
size_t len)
11361147
{
@@ -1242,18 +1253,42 @@ static int vsock_dgram_connect(struct socket *sock,
12421253
memcpy(&vsk->remote_addr, remote_addr, sizeof(vsk->remote_addr));
12431254
sock->state = SS_CONNECTED;
12441255

1256+
/* sock map disallows redirection of non-TCP sockets with sk_state !=
1257+
* TCP_ESTABLISHED (see sock_map_redirect_allowed()), so we set
1258+
* TCP_ESTABLISHED here to allow redirection of connected vsock dgrams.
1259+
*
1260+
* This doesn't seem to be abnormal state for datagram sockets, as the
1261+
* same approach can be see in other datagram socket types as well
1262+
* (such as unix sockets).
1263+
*/
1264+
sk->sk_state = TCP_ESTABLISHED;
1265+
12451266
out:
12461267
release_sock(sk);
12471268
return err;
12481269
}
12491270

1250-
static int vsock_dgram_recvmsg(struct socket *sock, struct msghdr *msg,
1251-
size_t len, int flags)
1271+
int vsock_dgram_recvmsg(struct socket *sock, struct msghdr *msg,
1272+
size_t len, int flags)
12521273
{
1253-
struct vsock_sock *vsk = vsock_sk(sock->sk);
1274+
#ifdef CONFIG_BPF_SYSCALL
1275+
const struct proto *prot;
1276+
#endif
1277+
struct vsock_sock *vsk;
1278+
struct sock *sk;
1279+
1280+
sk = sock->sk;
1281+
vsk = vsock_sk(sk);
1282+
1283+
#ifdef CONFIG_BPF_SYSCALL
1284+
prot = READ_ONCE(sk->sk_prot);
1285+
if (prot != &vsock_proto)
1286+
return prot->recvmsg(sk, msg, len, flags, NULL);
1287+
#endif
12541288

12551289
return vsk->transport->dgram_dequeue(vsk, msg, len, flags);
12561290
}
1291+
EXPORT_SYMBOL_GPL(vsock_dgram_recvmsg);
12571292

12581293
static const struct proto_ops vsock_dgram_ops = {
12591294
.family = PF_VSOCK,
@@ -1272,6 +1307,7 @@ static const struct proto_ops vsock_dgram_ops = {
12721307
.recvmsg = vsock_dgram_recvmsg,
12731308
.mmap = sock_no_mmap,
12741309
.sendpage = sock_no_sendpage,
1310+
.read_skb = vsock_read_skb,
12751311
};
12761312

12771313
static int vsock_transport_cancel_pkt(struct vsock_sock *vsk)
@@ -2086,13 +2122,16 @@ static int __vsock_seqpacket_recvmsg(struct sock *sk, struct msghdr *msg,
20862122
return err;
20872123
}
20882124

2089-
static int
2125+
int
20902126
vsock_connectible_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
20912127
int flags)
20922128
{
20932129
struct sock *sk;
20942130
struct vsock_sock *vsk;
20952131
const struct vsock_transport *transport;
2132+
#ifdef CONFIG_BPF_SYSCALL
2133+
const struct proto *prot;
2134+
#endif
20962135
int err;
20972136

20982137
sk = sock->sk;
@@ -2139,6 +2178,14 @@ vsock_connectible_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
21392178
goto out;
21402179
}
21412180

2181+
#ifdef CONFIG_BPF_SYSCALL
2182+
prot = READ_ONCE(sk->sk_prot);
2183+
if (prot != &vsock_proto) {
2184+
release_sock(sk);
2185+
return prot->recvmsg(sk, msg, len, flags, NULL);
2186+
}
2187+
#endif
2188+
21422189
if (sk->sk_type == SOCK_STREAM)
21432190
err = __vsock_stream_recvmsg(sk, msg, len, flags);
21442191
else
@@ -2148,6 +2195,7 @@ vsock_connectible_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
21482195
release_sock(sk);
21492196
return err;
21502197
}
2198+
EXPORT_SYMBOL_GPL(vsock_connectible_recvmsg);
21512199

21522200
static int vsock_set_rcvlowat(struct sock *sk, int val)
21532201
{
@@ -2188,6 +2236,7 @@ static const struct proto_ops vsock_stream_ops = {
21882236
.mmap = sock_no_mmap,
21892237
.sendpage = sock_no_sendpage,
21902238
.set_rcvlowat = vsock_set_rcvlowat,
2239+
.read_skb = vsock_read_skb,
21912240
};
21922241

21932242
static const struct proto_ops vsock_seqpacket_ops = {
@@ -2209,6 +2258,7 @@ static const struct proto_ops vsock_seqpacket_ops = {
22092258
.recvmsg = vsock_connectible_recvmsg,
22102259
.mmap = sock_no_mmap,
22112260
.sendpage = sock_no_sendpage,
2261+
.read_skb = vsock_read_skb,
22122262
};
22132263

22142264
static int vsock_create(struct net *net, struct socket *sock,
@@ -2348,6 +2398,8 @@ static int __init vsock_init(void)
23482398
goto err_unregister_proto;
23492399
}
23502400

2401+
vsock_bpf_build_proto();
2402+
23512403
return 0;
23522404

23532405
err_unregister_proto:

Diff for: net/vmw_vsock/virtio_transport.c

+2
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,8 @@ static struct virtio_transport virtio_transport = {
457457
.notify_send_pre_enqueue = virtio_transport_notify_send_pre_enqueue,
458458
.notify_send_post_enqueue = virtio_transport_notify_send_post_enqueue,
459459
.notify_buffer_size = virtio_transport_notify_buffer_size,
460+
461+
.read_skb = virtio_transport_read_skb,
460462
},
461463

462464
.send_pkt = virtio_transport_send_pkt,

Diff for: net/vmw_vsock/virtio_transport_common.c

+25
Original file line numberDiff line numberDiff line change
@@ -1418,6 +1418,31 @@ int virtio_transport_purge_skbs(void *vsk, struct sk_buff_head *queue)
14181418
}
14191419
EXPORT_SYMBOL_GPL(virtio_transport_purge_skbs);
14201420

1421+
int virtio_transport_read_skb(struct vsock_sock *vsk, skb_read_actor_t recv_actor)
1422+
{
1423+
struct virtio_vsock_sock *vvs = vsk->trans;
1424+
struct sock *sk = sk_vsock(vsk);
1425+
struct sk_buff *skb;
1426+
int off = 0;
1427+
int copied;
1428+
int err;
1429+
1430+
spin_lock_bh(&vvs->rx_lock);
1431+
/* Use __skb_recv_datagram() for race-free handling of the receive. It
1432+
* works for types other than dgrams.
1433+
*/
1434+
skb = __skb_recv_datagram(sk, &vvs->rx_queue, MSG_DONTWAIT, &off, &err);
1435+
spin_unlock_bh(&vvs->rx_lock);
1436+
1437+
if (!skb)
1438+
return err;
1439+
1440+
copied = recv_actor(sk, skb);
1441+
kfree_skb(skb);
1442+
return copied;
1443+
}
1444+
EXPORT_SYMBOL_GPL(virtio_transport_read_skb);
1445+
14211446
MODULE_LICENSE("GPL v2");
14221447
MODULE_AUTHOR("Asias He");
14231448
MODULE_DESCRIPTION("common code for virtio vsock");

0 commit comments

Comments
 (0)