Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

vsock: add netns support to virtio transports

Add netns support to loopback and vhost. Keep netns disabled for
virtio-vsock, but add necessary changes to comply with common API
updates.

This is the patch in the series when vhost-vsock namespaces actually
come online.

Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
Signed-off-by: Bobby Eshleman <bobbyeshleman@meta.com>
Link: https://patch.msgid.link/20260121-vsock-vmtest-v16-3-2859a7512097@meta.com
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>

authored by

Bobby Eshleman and committed by
Paolo Abeni
a6968632 a6ae12a5

+84 -40
+27 -11
drivers/vhost/vsock.c
··· 48 48 struct vhost_vsock { 49 49 struct vhost_dev dev; 50 50 struct vhost_virtqueue vqs[2]; 51 + struct net *net; 52 + netns_tracker ns_tracker; 51 53 52 54 /* Link to global vhost_vsock_hash, writes use vhost_vsock_mutex */ 53 55 struct hlist_node hash; ··· 71 69 /* Callers must be in an RCU read section or hold the vhost_vsock_mutex. 72 70 * The return value can only be dereferenced while within the section. 73 71 */ 74 - static struct vhost_vsock *vhost_vsock_get(u32 guest_cid) 72 + static struct vhost_vsock *vhost_vsock_get(u32 guest_cid, struct net *net) 75 73 { 76 74 struct vhost_vsock *vsock; 77 75 ··· 83 81 if (other_cid == 0) 84 82 continue; 85 83 86 - if (other_cid == guest_cid) 84 + if (other_cid == guest_cid && 85 + vsock_net_check_mode(net, vsock->net)) 87 86 return vsock; 88 - 89 87 } 90 88 91 89 return NULL; ··· 274 272 } 275 273 276 274 static int 277 - vhost_transport_send_pkt(struct sk_buff *skb) 275 + vhost_transport_send_pkt(struct sk_buff *skb, struct net *net) 278 276 { 279 277 struct virtio_vsock_hdr *hdr = virtio_vsock_hdr(skb); 280 278 struct vhost_vsock *vsock; ··· 283 281 rcu_read_lock(); 284 282 285 283 /* Find the vhost_vsock according to guest context id */ 286 - vsock = vhost_vsock_get(le64_to_cpu(hdr->dst_cid)); 284 + vsock = vhost_vsock_get(le64_to_cpu(hdr->dst_cid), net); 287 285 if (!vsock) { 288 286 rcu_read_unlock(); 289 287 kfree_skb(skb); ··· 310 308 rcu_read_lock(); 311 309 312 310 /* Find the vhost_vsock according to guest context id */ 313 - vsock = vhost_vsock_get(vsk->remote_addr.svm_cid); 311 + vsock = vhost_vsock_get(vsk->remote_addr.svm_cid, 312 + sock_net(sk_vsock(vsk))); 314 313 if (!vsock) 315 314 goto out; 316 315 ··· 413 410 static bool vhost_transport_seqpacket_allow(struct vsock_sock *vsk, 414 411 u32 remote_cid); 415 412 413 + static bool 414 + vhost_transport_stream_allow(struct vsock_sock *vsk, u32 cid, u32 port) 415 + { 416 + return true; 417 + } 418 + 416 419 static struct virtio_transport vhost_transport = { 417 420 .transport = { 418 421 .module = THIS_MODULE, ··· 443 434 .stream_has_space = virtio_transport_stream_has_space, 444 435 .stream_rcvhiwat = virtio_transport_stream_rcvhiwat, 445 436 .stream_is_active = virtio_transport_stream_is_active, 446 - .stream_allow = virtio_transport_stream_allow, 437 + .stream_allow = vhost_transport_stream_allow, 447 438 448 439 .seqpacket_dequeue = virtio_transport_seqpacket_dequeue, 449 440 .seqpacket_enqueue = virtio_transport_seqpacket_enqueue, ··· 476 467 static bool vhost_transport_seqpacket_allow(struct vsock_sock *vsk, 477 468 u32 remote_cid) 478 469 { 470 + struct net *net = sock_net(sk_vsock(vsk)); 479 471 struct vhost_vsock *vsock; 480 472 bool seqpacket_allow = false; 481 473 482 474 rcu_read_lock(); 483 - vsock = vhost_vsock_get(remote_cid); 475 + vsock = vhost_vsock_get(remote_cid, net); 484 476 485 477 if (vsock) 486 478 seqpacket_allow = vsock->seqpacket_allow; ··· 552 542 if (le64_to_cpu(hdr->src_cid) == vsock->guest_cid && 553 543 le64_to_cpu(hdr->dst_cid) == 554 544 vhost_transport_get_local_cid()) 555 - virtio_transport_recv_pkt(&vhost_transport, skb); 545 + virtio_transport_recv_pkt(&vhost_transport, skb, 546 + vsock->net); 556 547 else 557 548 kfree_skb(skb); 558 549 ··· 670 659 { 671 660 struct vhost_virtqueue **vqs; 672 661 struct vhost_vsock *vsock; 662 + struct net *net; 673 663 int ret; 674 664 675 665 /* This struct is large and allocation could fail, fall back to vmalloc ··· 685 673 ret = -ENOMEM; 686 674 goto out; 687 675 } 676 + 677 + net = current->nsproxy->net_ns; 678 + vsock->net = get_net_track(net, &vsock->ns_tracker, GFP_KERNEL); 688 679 689 680 vsock->guest_cid = 0; /* no CID assigned yet */ 690 681 vsock->seqpacket_allow = false; ··· 730 715 rcu_read_lock(); 731 716 732 717 /* If the peer is still valid, no need to reset connection */ 733 - if (vhost_vsock_get(vsk->remote_addr.svm_cid)) { 718 + if (vhost_vsock_get(vsk->remote_addr.svm_cid, sock_net(sk))) { 734 719 rcu_read_unlock(); 735 720 return; 736 721 } ··· 779 764 virtio_vsock_skb_queue_purge(&vsock->send_pkt_queue); 780 765 781 766 vhost_dev_cleanup(&vsock->dev); 767 + put_net_track(vsock->net, &vsock->ns_tracker); 782 768 kfree(vsock->dev.vqs); 783 769 vhost_vsock_free(vsock); 784 770 return 0; ··· 806 790 807 791 /* Refuse if CID is already in use */ 808 792 mutex_lock(&vhost_vsock_mutex); 809 - other = vhost_vsock_get(guest_cid); 793 + other = vhost_vsock_get(guest_cid, vsock->net); 810 794 if (other && other != vsock) { 811 795 mutex_unlock(&vhost_vsock_mutex); 812 796 return -EADDRINUSE;
+3 -2
include/linux/virtio_vsock.h
··· 173 173 u32 remote_cid, remote_port; 174 174 struct vsock_sock *vsk; 175 175 struct msghdr *msg; 176 + struct net *net; 176 177 u32 pkt_len; 177 178 u16 type; 178 179 u16 op; ··· 186 185 struct vsock_transport transport; 187 186 188 187 /* Takes ownership of the packet */ 189 - int (*send_pkt)(struct sk_buff *skb); 188 + int (*send_pkt)(struct sk_buff *skb, struct net *net); 190 189 191 190 /* Used in MSG_ZEROCOPY mode. Checks, that provided data 192 191 * (number of buffers) could be transmitted with zerocopy ··· 281 280 void virtio_transport_destruct(struct vsock_sock *vsk); 282 281 283 282 void virtio_transport_recv_pkt(struct virtio_transport *t, 284 - struct sk_buff *skb); 283 + struct sk_buff *skb, struct net *net); 285 284 void virtio_transport_inc_tx_pkt(struct virtio_vsock_sock *vvs, struct sk_buff *skb); 286 285 u32 virtio_transport_get_credit(struct virtio_vsock_sock *vvs, u32 wanted); 287 286 void virtio_transport_put_credit(struct virtio_vsock_sock *vvs, u32 credit);
+11 -2
net/vmw_vsock/virtio_transport.c
··· 231 231 } 232 232 233 233 static int 234 - virtio_transport_send_pkt(struct sk_buff *skb) 234 + virtio_transport_send_pkt(struct sk_buff *skb, struct net *net) 235 235 { 236 236 struct virtio_vsock_hdr *hdr; 237 237 struct virtio_vsock *vsock; ··· 536 536 return true; 537 537 } 538 538 539 + bool virtio_transport_stream_allow(struct vsock_sock *vsk, u32 cid, u32 port) 540 + { 541 + return vsock_net_mode_global(vsk); 542 + } 543 + 539 544 static bool virtio_transport_seqpacket_allow(struct vsock_sock *vsk, 540 545 u32 remote_cid); 541 546 ··· 670 665 virtio_vsock_skb_put(skb, payload_len); 671 666 672 667 virtio_transport_deliver_tap_pkt(skb); 673 - virtio_transport_recv_pkt(&virtio_transport, skb); 668 + 669 + /* Force virtio-transport into global mode since it 670 + * does not yet support local-mode namespacing. 671 + */ 672 + virtio_transport_recv_pkt(&virtio_transport, skb, NULL); 674 673 } 675 674 } while (!virtqueue_enable_cb(vq)); 676 675
+32 -22
net/vmw_vsock/virtio_transport_common.c
··· 414 414 415 415 virtio_transport_inc_tx_pkt(vvs, skb); 416 416 417 - ret = t_ops->send_pkt(skb); 417 + ret = t_ops->send_pkt(skb, info->net); 418 418 if (ret < 0) 419 419 break; 420 420 ··· 526 526 struct virtio_vsock_pkt_info info = { 527 527 .op = VIRTIO_VSOCK_OP_CREDIT_UPDATE, 528 528 .vsk = vsk, 529 + .net = sock_net(sk_vsock(vsk)), 529 530 }; 530 531 531 532 return virtio_transport_send_pkt_info(vsk, &info); ··· 1056 1055 } 1057 1056 EXPORT_SYMBOL_GPL(virtio_transport_stream_is_active); 1058 1057 1059 - bool virtio_transport_stream_allow(struct vsock_sock *vsk, u32 cid, u32 port) 1060 - { 1061 - return vsock_net_mode(sock_net(sk_vsock(vsk))) == VSOCK_NET_MODE_GLOBAL; 1062 - } 1063 - EXPORT_SYMBOL_GPL(virtio_transport_stream_allow); 1064 - 1065 1058 int virtio_transport_dgram_bind(struct vsock_sock *vsk, 1066 1059 struct sockaddr_vm *addr) 1067 1060 { ··· 1074 1079 struct virtio_vsock_pkt_info info = { 1075 1080 .op = VIRTIO_VSOCK_OP_REQUEST, 1076 1081 .vsk = vsk, 1082 + .net = sock_net(sk_vsock(vsk)), 1077 1083 }; 1078 1084 1079 1085 return virtio_transport_send_pkt_info(vsk, &info); ··· 1090 1094 (mode & SEND_SHUTDOWN ? 1091 1095 VIRTIO_VSOCK_SHUTDOWN_SEND : 0), 1092 1096 .vsk = vsk, 1097 + .net = sock_net(sk_vsock(vsk)), 1093 1098 }; 1094 1099 1095 1100 return virtio_transport_send_pkt_info(vsk, &info); ··· 1117 1120 .msg = msg, 1118 1121 .pkt_len = len, 1119 1122 .vsk = vsk, 1123 + .net = sock_net(sk_vsock(vsk)), 1120 1124 }; 1121 1125 1122 1126 return virtio_transport_send_pkt_info(vsk, &info); ··· 1155 1157 .op = VIRTIO_VSOCK_OP_RST, 1156 1158 .reply = !!skb, 1157 1159 .vsk = vsk, 1160 + .net = sock_net(sk_vsock(vsk)), 1158 1161 }; 1159 1162 1160 1163 /* Send RST only if the original pkt is not a RST pkt */ ··· 1167 1168 1168 1169 /* Normally packets are associated with a socket. There may be no socket if an 1169 1170 * attempt was made to connect to a socket that does not exist. 1171 + * 1172 + * net refers to the namespace of whoever sent the invalid message. For 1173 + * loopback, this is the namespace of the socket. For vhost, this is the 1174 + * namespace of the VM (i.e., vhost_vsock). 1170 1175 */ 1171 1176 static int virtio_transport_reset_no_sock(const struct virtio_transport *t, 1172 - struct sk_buff *skb) 1177 + struct sk_buff *skb, struct net *net) 1173 1178 { 1174 1179 struct virtio_vsock_hdr *hdr = virtio_vsock_hdr(skb); 1175 1180 struct virtio_vsock_pkt_info info = { ··· 1186 1183 * sock_net(sk) until the reply skb is freed. 1187 1184 */ 1188 1185 .vsk = vsock_sk(skb->sk), 1186 + 1187 + /* net is not defined here because we pass it directly to 1188 + * t->send_pkt(), instead of relying on 1189 + * virtio_transport_send_pkt_info() to pass it. It is not needed 1190 + * by virtio_transport_alloc_skb(). 1191 + */ 1189 1192 }; 1190 1193 struct sk_buff *reply; 1191 1194 ··· 1210 1201 if (!reply) 1211 1202 return -ENOMEM; 1212 1203 1213 - return t->send_pkt(reply); 1204 + return t->send_pkt(reply, net); 1214 1205 } 1215 1206 1216 1207 /* This function should be called with sk_lock held and SOCK_DONE set */ ··· 1494 1485 .remote_port = le32_to_cpu(hdr->src_port), 1495 1486 .reply = true, 1496 1487 .vsk = vsk, 1488 + .net = sock_net(sk_vsock(vsk)), 1497 1489 }; 1498 1490 1499 1491 return virtio_transport_send_pkt_info(vsk, &info); ··· 1537 1527 int ret; 1538 1528 1539 1529 if (le16_to_cpu(hdr->op) != VIRTIO_VSOCK_OP_REQUEST) { 1540 - virtio_transport_reset_no_sock(t, skb); 1530 + virtio_transport_reset_no_sock(t, skb, sock_net(sk)); 1541 1531 return -EINVAL; 1542 1532 } 1543 1533 1544 1534 if (sk_acceptq_is_full(sk)) { 1545 - virtio_transport_reset_no_sock(t, skb); 1535 + virtio_transport_reset_no_sock(t, skb, sock_net(sk)); 1546 1536 return -ENOMEM; 1547 1537 } 1548 1538 ··· 1550 1540 * Subsequent enqueues would lead to a memory leak. 1551 1541 */ 1552 1542 if (sk->sk_shutdown == SHUTDOWN_MASK) { 1553 - virtio_transport_reset_no_sock(t, skb); 1543 + virtio_transport_reset_no_sock(t, skb, sock_net(sk)); 1554 1544 return -ESHUTDOWN; 1555 1545 } 1556 1546 1557 1547 child = vsock_create_connected(sk); 1558 1548 if (!child) { 1559 - virtio_transport_reset_no_sock(t, skb); 1549 + virtio_transport_reset_no_sock(t, skb, sock_net(sk)); 1560 1550 return -ENOMEM; 1561 1551 } 1562 1552 ··· 1578 1568 */ 1579 1569 if (ret || vchild->transport != &t->transport) { 1580 1570 release_sock(child); 1581 - virtio_transport_reset_no_sock(t, skb); 1571 + virtio_transport_reset_no_sock(t, skb, sock_net(sk)); 1582 1572 sock_put(child); 1583 1573 return ret; 1584 1574 } ··· 1606 1596 * lock. 1607 1597 */ 1608 1598 void virtio_transport_recv_pkt(struct virtio_transport *t, 1609 - struct sk_buff *skb) 1599 + struct sk_buff *skb, struct net *net) 1610 1600 { 1611 1601 struct virtio_vsock_hdr *hdr = virtio_vsock_hdr(skb); 1612 1602 struct sockaddr_vm src, dst; ··· 1629 1619 le32_to_cpu(hdr->fwd_cnt)); 1630 1620 1631 1621 if (!virtio_transport_valid_type(le16_to_cpu(hdr->type))) { 1632 - (void)virtio_transport_reset_no_sock(t, skb); 1622 + (void)virtio_transport_reset_no_sock(t, skb, net); 1633 1623 goto free_pkt; 1634 1624 } 1635 1625 1636 1626 /* The socket must be in connected or bound table 1637 1627 * otherwise send reset back 1638 1628 */ 1639 - sk = vsock_find_connected_socket(&src, &dst); 1629 + sk = vsock_find_connected_socket_net(&src, &dst, net); 1640 1630 if (!sk) { 1641 - sk = vsock_find_bound_socket(&dst); 1631 + sk = vsock_find_bound_socket_net(&dst, net); 1642 1632 if (!sk) { 1643 - (void)virtio_transport_reset_no_sock(t, skb); 1633 + (void)virtio_transport_reset_no_sock(t, skb, net); 1644 1634 goto free_pkt; 1645 1635 } 1646 1636 } 1647 1637 1648 1638 if (virtio_transport_get_type(sk) != le16_to_cpu(hdr->type)) { 1649 - (void)virtio_transport_reset_no_sock(t, skb); 1639 + (void)virtio_transport_reset_no_sock(t, skb, net); 1650 1640 sock_put(sk); 1651 1641 goto free_pkt; 1652 1642 } ··· 1665 1655 */ 1666 1656 if (sock_flag(sk, SOCK_DONE) || 1667 1657 (sk->sk_state != TCP_LISTEN && vsk->transport != &t->transport)) { 1668 - (void)virtio_transport_reset_no_sock(t, skb); 1658 + (void)virtio_transport_reset_no_sock(t, skb, net); 1669 1659 release_sock(sk); 1670 1660 sock_put(sk); 1671 1661 goto free_pkt; ··· 1697 1687 kfree_skb(skb); 1698 1688 break; 1699 1689 default: 1700 - (void)virtio_transport_reset_no_sock(t, skb); 1690 + (void)virtio_transport_reset_no_sock(t, skb, net); 1701 1691 kfree_skb(skb); 1702 1692 break; 1703 1693 }
+11 -3
net/vmw_vsock/vsock_loopback.c
··· 26 26 return VMADDR_CID_LOCAL; 27 27 } 28 28 29 - static int vsock_loopback_send_pkt(struct sk_buff *skb) 29 + static int vsock_loopback_send_pkt(struct sk_buff *skb, struct net *net) 30 30 { 31 31 struct vsock_loopback *vsock = &the_vsock_loopback; 32 32 int len = skb->len; ··· 48 48 49 49 static bool vsock_loopback_seqpacket_allow(struct vsock_sock *vsk, 50 50 u32 remote_cid); 51 + 52 + static bool vsock_loopback_stream_allow(struct vsock_sock *vsk, u32 cid, 53 + u32 port) 54 + { 55 + return true; 56 + } 57 + 51 58 static bool vsock_loopback_msgzerocopy_allow(void) 52 59 { 53 60 return true; ··· 84 77 .stream_has_space = virtio_transport_stream_has_space, 85 78 .stream_rcvhiwat = virtio_transport_stream_rcvhiwat, 86 79 .stream_is_active = virtio_transport_stream_is_active, 87 - .stream_allow = virtio_transport_stream_allow, 80 + .stream_allow = vsock_loopback_stream_allow, 88 81 89 82 .seqpacket_dequeue = virtio_transport_seqpacket_dequeue, 90 83 .seqpacket_enqueue = virtio_transport_seqpacket_enqueue, ··· 139 132 */ 140 133 virtio_transport_consume_skb_sent(skb, false); 141 134 virtio_transport_deliver_tap_pkt(skb); 142 - virtio_transport_recv_pkt(&loopback_transport, skb); 135 + virtio_transport_recv_pkt(&loopback_transport, skb, 136 + sock_net(skb->sk)); 143 137 } 144 138 } 145 139