#include <linux/types.h>
#include <linux/bitops.h>
#include <linux/cred.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/kmod.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/net.h>
#include <linux/poll.h>
#include <linux/skbuff.h>
#include <linux/smp.h>
#include <linux/socket.h>
#include <linux/stddef.h>
#include <linux/unistd.h>
#include <linux/wait.h>
#include <linux/workqueue.h>
#include <net/sock.h>
#include <net/af_vsock.h>
#include "vmci_transport_notify.h"
static int vmci_transport_recv_dgram_cb(void *data, struct vmci_datagram *dg);
static int vmci_transport_recv_stream_cb(void *data, struct vmci_datagram *dg);
static void vmci_transport_peer_detach_cb(u32 sub_id,
const struct vmci_event_data *ed,
void *client_data);
static void vmci_transport_recv_pkt_work(struct work_struct *work);
static void vmci_transport_cleanup(struct work_struct *work);
static int vmci_transport_recv_listen(struct sock *sk,
struct vmci_transport_packet *pkt);
static int vmci_transport_recv_connecting_server(
struct sock *sk,
struct sock *pending,
struct vmci_transport_packet *pkt);
static int vmci_transport_recv_connecting_client(
struct sock *sk,
struct vmci_transport_packet *pkt);
static int vmci_transport_recv_connecting_client_negotiate(
struct sock *sk,
struct vmci_transport_packet *pkt);
static int vmci_transport_recv_connecting_client_invalid(
struct sock *sk,
struct vmci_transport_packet *pkt);
static int vmci_transport_recv_connected(struct sock *sk,
struct vmci_transport_packet *pkt);
static bool vmci_transport_old_proto_override(bool *old_pkt_proto);
static u16 vmci_transport_new_proto_supported_versions(void);
static bool vmci_transport_proto_to_notify_struct(struct sock *sk, u16 *proto,
bool old_pkt_proto);
static bool vmci_check_transport(struct vsock_sock *vsk);
struct vmci_transport_recv_pkt_info { … };
static LIST_HEAD(vmci_transport_cleanup_list);
static DEFINE_SPINLOCK(vmci_transport_cleanup_lock);
static DECLARE_WORK(vmci_transport_cleanup_work, vmci_transport_cleanup);
static struct vmci_handle vmci_transport_stream_handle = …;
static u32 vmci_transport_qp_resumed_sub_id = …;
static int PROTOCOL_OVERRIDE = …;
static struct vsock_transport vmci_transport;
static s32 vmci_transport_error_to_vsock_error(s32 vmci_error)
{ … }
static u32 vmci_transport_peer_rid(u32 peer_cid)
{ … }
static inline void
vmci_transport_packet_init(struct vmci_transport_packet *pkt,
struct sockaddr_vm *src,
struct sockaddr_vm *dst,
u8 type,
u64 size,
u64 mode,
struct vmci_transport_waiting_info *wait,
u16 proto,
struct vmci_handle handle)
{ … }
static inline void
vmci_transport_packet_get_addresses(struct vmci_transport_packet *pkt,
struct sockaddr_vm *local,
struct sockaddr_vm *remote)
{ … }
static int
__vmci_transport_send_control_pkt(struct vmci_transport_packet *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,
bool convert_error)
{ … }
static int
vmci_transport_reply_control_pkt_fast(struct vmci_transport_packet *pkt,
enum vmci_transport_packet_type type,
u64 size,
u64 mode,
struct vmci_transport_waiting_info *wait,
struct vmci_handle handle)
{ … }
static int
vmci_transport_send_control_pkt_bh(struct sockaddr_vm *src,
struct sockaddr_vm *dst,
enum vmci_transport_packet_type type,
u64 size,
u64 mode,
struct vmci_transport_waiting_info *wait,
struct vmci_handle handle)
{ … }
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)
{ … }
static int
vmci_transport_send_control_pkt(struct sock *sk,
enum vmci_transport_packet_type type,
u64 size,
u64 mode,
struct vmci_transport_waiting_info *wait,
u16 proto,
struct vmci_handle handle)
{ … }
static int vmci_transport_send_reset_bh(struct sockaddr_vm *dst,
struct sockaddr_vm *src,
struct vmci_transport_packet *pkt)
{ … }
static int vmci_transport_send_reset(struct sock *sk,
struct vmci_transport_packet *pkt)
{ … }
static int vmci_transport_send_negotiate(struct sock *sk, size_t size)
{ … }
static int vmci_transport_send_negotiate2(struct sock *sk, size_t size,
u16 version)
{ … }
static int vmci_transport_send_qp_offer(struct sock *sk,
struct vmci_handle handle)
{ … }
static int vmci_transport_send_attach(struct sock *sk,
struct vmci_handle handle)
{ … }
static int vmci_transport_reply_reset(struct vmci_transport_packet *pkt)
{ … }
static int vmci_transport_send_invalid_bh(struct sockaddr_vm *dst,
struct sockaddr_vm *src)
{ … }
int vmci_transport_send_wrote_bh(struct sockaddr_vm *dst,
struct sockaddr_vm *src)
{ … }
int vmci_transport_send_read_bh(struct sockaddr_vm *dst,
struct sockaddr_vm *src)
{ … }
int vmci_transport_send_wrote(struct sock *sk)
{ … }
int vmci_transport_send_read(struct sock *sk)
{ … }
int vmci_transport_send_waiting_write(struct sock *sk,
struct vmci_transport_waiting_info *wait)
{ … }
int vmci_transport_send_waiting_read(struct sock *sk,
struct vmci_transport_waiting_info *wait)
{ … }
static int vmci_transport_shutdown(struct vsock_sock *vsk, int mode)
{ … }
static int vmci_transport_send_conn_request(struct sock *sk, size_t size)
{ … }
static int vmci_transport_send_conn_request2(struct sock *sk, size_t size,
u16 version)
{ … }
static struct sock *vmci_transport_get_pending(
struct sock *listener,
struct vmci_transport_packet *pkt)
{ … }
static void vmci_transport_release_pending(struct sock *pending)
{ … }
static bool vmci_transport_is_trusted(struct vsock_sock *vsock, u32 peer_cid)
{ … }
static bool vmci_transport_allow_dgram(struct vsock_sock *vsock, u32 peer_cid)
{ … }
static int
vmci_transport_queue_pair_alloc(struct vmci_qp **qpair,
struct vmci_handle *handle,
u64 produce_size,
u64 consume_size,
u32 peer, u32 flags, bool trusted)
{ … }
static int
vmci_transport_datagram_create_hnd(u32 resource_id,
u32 flags,
vmci_datagram_recv_cb recv_cb,
void *client_data,
struct vmci_handle *out_handle)
{ … }
static int vmci_transport_recv_dgram_cb(void *data, struct vmci_datagram *dg)
{ … }
static bool vmci_transport_stream_allow(u32 cid, u32 port)
{ … }
static int vmci_transport_recv_stream_cb(void *data, struct vmci_datagram *dg)
{ … }
static void vmci_transport_handle_detach(struct sock *sk)
{ … }
static void vmci_transport_peer_detach_cb(u32 sub_id,
const struct vmci_event_data *e_data,
void *client_data)
{ … }
static void vmci_transport_qp_resumed_cb(u32 sub_id,
const struct vmci_event_data *e_data,
void *client_data)
{ … }
static void vmci_transport_recv_pkt_work(struct work_struct *work)
{ … }
static int vmci_transport_recv_listen(struct sock *sk,
struct vmci_transport_packet *pkt)
{ … }
static int
vmci_transport_recv_connecting_server(struct sock *listener,
struct sock *pending,
struct vmci_transport_packet *pkt)
{ … }
static int
vmci_transport_recv_connecting_client(struct sock *sk,
struct vmci_transport_packet *pkt)
{ … }
static int vmci_transport_recv_connecting_client_negotiate(
struct sock *sk,
struct vmci_transport_packet *pkt)
{ … }
static int
vmci_transport_recv_connecting_client_invalid(struct sock *sk,
struct vmci_transport_packet *pkt)
{ … }
static int vmci_transport_recv_connected(struct sock *sk,
struct vmci_transport_packet *pkt)
{ … }
static int vmci_transport_socket_init(struct vsock_sock *vsk,
struct vsock_sock *psk)
{ … }
static void vmci_transport_free_resources(struct list_head *transport_list)
{ … }
static void vmci_transport_cleanup(struct work_struct *work)
{ … }
static void vmci_transport_destruct(struct vsock_sock *vsk)
{ … }
static void vmci_transport_release(struct vsock_sock *vsk)
{ … }
static int vmci_transport_dgram_bind(struct vsock_sock *vsk,
struct sockaddr_vm *addr)
{ … }
static int vmci_transport_dgram_enqueue(
struct vsock_sock *vsk,
struct sockaddr_vm *remote_addr,
struct msghdr *msg,
size_t len)
{ … }
static int vmci_transport_dgram_dequeue(struct vsock_sock *vsk,
struct msghdr *msg, size_t len,
int flags)
{ … }
static bool vmci_transport_dgram_allow(u32 cid, u32 port)
{ … }
static int vmci_transport_connect(struct vsock_sock *vsk)
{ … }
static ssize_t vmci_transport_stream_dequeue(
struct vsock_sock *vsk,
struct msghdr *msg,
size_t len,
int flags)
{ … }
static ssize_t vmci_transport_stream_enqueue(
struct vsock_sock *vsk,
struct msghdr *msg,
size_t len)
{ … }
static s64 vmci_transport_stream_has_data(struct vsock_sock *vsk)
{ … }
static s64 vmci_transport_stream_has_space(struct vsock_sock *vsk)
{ … }
static u64 vmci_transport_stream_rcvhiwat(struct vsock_sock *vsk)
{ … }
static bool vmci_transport_stream_is_active(struct vsock_sock *vsk)
{ … }
static int vmci_transport_notify_poll_in(
struct vsock_sock *vsk,
size_t target,
bool *data_ready_now)
{ … }
static int vmci_transport_notify_poll_out(
struct vsock_sock *vsk,
size_t target,
bool *space_available_now)
{ … }
static int vmci_transport_notify_recv_init(
struct vsock_sock *vsk,
size_t target,
struct vsock_transport_recv_notify_data *data)
{ … }
static int vmci_transport_notify_recv_pre_block(
struct vsock_sock *vsk,
size_t target,
struct vsock_transport_recv_notify_data *data)
{ … }
static int vmci_transport_notify_recv_pre_dequeue(
struct vsock_sock *vsk,
size_t target,
struct vsock_transport_recv_notify_data *data)
{ … }
static int vmci_transport_notify_recv_post_dequeue(
struct vsock_sock *vsk,
size_t target,
ssize_t copied,
bool data_read,
struct vsock_transport_recv_notify_data *data)
{ … }
static int vmci_transport_notify_send_init(
struct vsock_sock *vsk,
struct vsock_transport_send_notify_data *data)
{ … }
static int vmci_transport_notify_send_pre_block(
struct vsock_sock *vsk,
struct vsock_transport_send_notify_data *data)
{ … }
static int vmci_transport_notify_send_pre_enqueue(
struct vsock_sock *vsk,
struct vsock_transport_send_notify_data *data)
{ … }
static int vmci_transport_notify_send_post_enqueue(
struct vsock_sock *vsk,
ssize_t written,
struct vsock_transport_send_notify_data *data)
{ … }
static bool vmci_transport_old_proto_override(bool *old_pkt_proto)
{ … }
static bool vmci_transport_proto_to_notify_struct(struct sock *sk,
u16 *proto,
bool old_pkt_proto)
{ … }
static u16 vmci_transport_new_proto_supported_versions(void)
{ … }
static u32 vmci_transport_get_local_cid(void)
{ … }
static struct vsock_transport vmci_transport = …;
static bool vmci_check_transport(struct vsock_sock *vsk)
{ … }
static void vmci_vsock_transport_cb(bool is_host)
{ … }
static int __init vmci_transport_init(void)
{ … }
module_init(…) …;
static void __exit vmci_transport_exit(void)
{ … }
module_exit(vmci_transport_exit);
MODULE_AUTHOR(…) …;
MODULE_DESCRIPTION(…) …;
MODULE_VERSION(…) …;
MODULE_LICENSE(…) …;
MODULE_ALIAS(…) …;
MODULE_ALIAS_NETPROTO(…);