Skip to content

Commit 82dfb54

Browse files
Gerard Garciadavem330
authored andcommitted
VSOCK: Add virtio vsock vsockmon hooks
The virtio drivers deal with struct virtio_vsock_pkt. Add virtio_transport_deliver_tap_pkt(pkt) for handing packets to the vsockmon device. We call virtio_transport_deliver_tap_pkt(pkt) from net/vmw_vsock/virtio_transport.c and drivers/vhost/vsock.c instead of common code. This is because the drivers may drop packets before handing them to common code - we still want to capture them. Signed-off-by: Gerard Garcia <ggarcia@deic.uab.cat> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> Reviewed-by: Jorgen Hansen <jhansen@vmware.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 0b2e664 commit 82dfb54

File tree

4 files changed

+76
-0
lines changed

4 files changed

+76
-0
lines changed

drivers/vhost/vsock.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,11 @@ vhost_transport_do_send_pkt(struct vhost_vsock *vsock,
176176
restart_tx = true;
177177
}
178178

179+
/* Deliver to monitoring devices all correctly transmitted
180+
* packets.
181+
*/
182+
virtio_transport_deliver_tap_pkt(pkt);
183+
179184
virtio_transport_free_pkt(pkt);
180185
}
181186
if (added)
@@ -383,6 +388,9 @@ static void vhost_vsock_handle_tx_kick(struct vhost_work *work)
383388

384389
len = pkt->len;
385390

391+
/* Deliver to monitoring devices all received packets */
392+
virtio_transport_deliver_tap_pkt(pkt);
393+
386394
/* Only accept correctly addressed packets */
387395
if (le64_to_cpu(pkt->hdr.src_cid) == vsock->guest_cid)
388396
virtio_transport_recv_pkt(pkt);

include/linux/virtio_vsock.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,5 +153,6 @@ void virtio_transport_free_pkt(struct virtio_vsock_pkt *pkt);
153153
void virtio_transport_inc_tx_pkt(struct virtio_vsock_sock *vvs, struct virtio_vsock_pkt *pkt);
154154
u32 virtio_transport_get_credit(struct virtio_vsock_sock *vvs, u32 wanted);
155155
void virtio_transport_put_credit(struct virtio_vsock_sock *vvs, u32 credit);
156+
void virtio_transport_deliver_tap_pkt(struct virtio_vsock_pkt *pkt);
156157

157158
#endif /* _LINUX_VIRTIO_VSOCK_H */

net/vmw_vsock/virtio_transport.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,8 @@ virtio_transport_send_pkt_work(struct work_struct *work)
144144
list_del_init(&pkt->list);
145145
spin_unlock_bh(&vsock->send_pkt_list_lock);
146146

147+
virtio_transport_deliver_tap_pkt(pkt);
148+
147149
reply = pkt->reply;
148150

149151
sg_init_one(&hdr, &pkt->hdr, sizeof(pkt->hdr));
@@ -370,6 +372,7 @@ static void virtio_transport_rx_work(struct work_struct *work)
370372
}
371373

372374
pkt->len = len - sizeof(pkt->hdr);
375+
virtio_transport_deliver_tap_pkt(pkt);
373376
virtio_transport_recv_pkt(pkt);
374377
}
375378
} while (!virtqueue_enable_cb(vq));

net/vmw_vsock/virtio_transport_common.c

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <linux/virtio_ids.h>
1717
#include <linux/virtio_config.h>
1818
#include <linux/virtio_vsock.h>
19+
#include <uapi/linux/vsockmon.h>
1920

2021
#include <net/sock.h>
2122
#include <net/af_vsock.h>
@@ -85,6 +86,69 @@ virtio_transport_alloc_pkt(struct virtio_vsock_pkt_info *info,
8586
return NULL;
8687
}
8788

89+
/* Packet capture */
90+
static struct sk_buff *virtio_transport_build_skb(void *opaque)
91+
{
92+
struct virtio_vsock_pkt *pkt = opaque;
93+
unsigned char *t_hdr, *payload;
94+
struct af_vsockmon_hdr *hdr;
95+
struct sk_buff *skb;
96+
97+
skb = alloc_skb(sizeof(*hdr) + sizeof(pkt->hdr) + pkt->len,
98+
GFP_ATOMIC);
99+
if (!skb)
100+
return NULL;
101+
102+
hdr = (struct af_vsockmon_hdr *)skb_put(skb, sizeof(*hdr));
103+
104+
/* pkt->hdr is little-endian so no need to byteswap here */
105+
hdr->src_cid = pkt->hdr.src_cid;
106+
hdr->src_port = pkt->hdr.src_port;
107+
hdr->dst_cid = pkt->hdr.dst_cid;
108+
hdr->dst_port = pkt->hdr.dst_port;
109+
110+
hdr->transport = cpu_to_le16(AF_VSOCK_TRANSPORT_VIRTIO);
111+
hdr->len = cpu_to_le16(sizeof(pkt->hdr));
112+
memset(hdr->reserved, 0, sizeof(hdr->reserved));
113+
114+
switch (le16_to_cpu(pkt->hdr.op)) {
115+
case VIRTIO_VSOCK_OP_REQUEST:
116+
case VIRTIO_VSOCK_OP_RESPONSE:
117+
hdr->op = cpu_to_le16(AF_VSOCK_OP_CONNECT);
118+
break;
119+
case VIRTIO_VSOCK_OP_RST:
120+
case VIRTIO_VSOCK_OP_SHUTDOWN:
121+
hdr->op = cpu_to_le16(AF_VSOCK_OP_DISCONNECT);
122+
break;
123+
case VIRTIO_VSOCK_OP_RW:
124+
hdr->op = cpu_to_le16(AF_VSOCK_OP_PAYLOAD);
125+
break;
126+
case VIRTIO_VSOCK_OP_CREDIT_UPDATE:
127+
case VIRTIO_VSOCK_OP_CREDIT_REQUEST:
128+
hdr->op = cpu_to_le16(AF_VSOCK_OP_CONTROL);
129+
break;
130+
default:
131+
hdr->op = cpu_to_le16(AF_VSOCK_OP_UNKNOWN);
132+
break;
133+
}
134+
135+
t_hdr = skb_put(skb, sizeof(pkt->hdr));
136+
memcpy(t_hdr, &pkt->hdr, sizeof(pkt->hdr));
137+
138+
if (pkt->len) {
139+
payload = skb_put(skb, pkt->len);
140+
memcpy(payload, pkt->buf, pkt->len);
141+
}
142+
143+
return skb;
144+
}
145+
146+
void virtio_transport_deliver_tap_pkt(struct virtio_vsock_pkt *pkt)
147+
{
148+
vsock_deliver_tap(virtio_transport_build_skb, pkt);
149+
}
150+
EXPORT_SYMBOL_GPL(virtio_transport_deliver_tap_pkt);
151+
88152
static int virtio_transport_send_pkt_info(struct vsock_sock *vsk,
89153
struct virtio_vsock_pkt_info *info)
90154
{

0 commit comments

Comments
 (0)