Previously, vhost library lacks the support to the vhost backend
other than net such as adding private data or registering vhost-user
message handlers. This patch fills the gap by adding data pointer and
vhost-user pre and post message handlers to vhost library.

Signed-off-by: Fan Zhang <roy.fan.zh...@intel.com>
---
 lib/librte_vhost/vhost.c      |  2 +-
 lib/librte_vhost/vhost.h      | 53 +++++++++++++++++++++++++++++++++++++++++--
 lib/librte_vhost/vhost_user.c | 31 ++++++++++++++++++++++++-
 3 files changed, 82 insertions(+), 4 deletions(-)

diff --git a/lib/librte_vhost/vhost.c b/lib/librte_vhost/vhost.c
index f6f12a03b..99f8b01fb 100644
--- a/lib/librte_vhost/vhost.c
+++ b/lib/librte_vhost/vhost.c
@@ -1,5 +1,5 @@
 /* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
+ * Copyright(c) 2010-2017 Intel Corporation
  */
 
 #include <linux/vhost.h>
diff --git a/lib/librte_vhost/vhost.h b/lib/librte_vhost/vhost.h
index 4981e6d0c..fb2f050eb 100644
--- a/lib/librte_vhost/vhost.h
+++ b/lib/librte_vhost/vhost.h
@@ -1,5 +1,5 @@
 /* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
+ * Copyright(c) 2010-2018 Intel Corporation
  */
 
 #ifndef _VHOST_NET_CDEV_H_
@@ -211,6 +211,51 @@ struct guest_page {
 };
 
 /**
+ * function prototype for the vhost backend to handler specific vhost user
+ * messages prior to the master message handling
+ *
+ * @param vid
+ *  vhost device id
+ * @param msg
+ *  Message pointer.
+ * @param require_reply
+ *  If the handler requires sending a reply, this varaible shall be written 1,
+ *  otherwise 0.
+ * @param skip_master
+ *  If the handler requires skipping the master message handling, this variable
+ *  shall be written 1, otherwise 0.
+ * @return
+ *  0 on success, -1 on failure
+ */
+typedef int (*vhost_msg_pre_handle)(int vid, void *msg,
+               uint32_t *require_reply, uint32_t *skip_master);
+
+/**
+ * function prototype for the vhost backend to handler specific vhost user
+ * messages after the master message handling is done
+ *
+ * @param vid
+ *  vhost device id
+ * @param msg
+ *  Message pointer.
+ * @param require_reply
+ *  If the handler requires sending a reply, this varaible shall be written 1,
+ *  otherwise 0.
+ * @return
+ *  0 on success, -1 on failure
+ */
+typedef int (*vhost_msg_post_handle)(int vid, void *msg,
+               uint32_t *require_reply);
+
+/**
+ * pre and post vhost user message handlers
+ */
+struct vhost_user_extern_ops {
+       vhost_msg_pre_handle pre_msg_handle;
+       vhost_msg_post_handle post_msg_handle;
+};
+
+/**
  * Device structure contains all configuration information relating
  * to the device.
  */
@@ -242,8 +287,12 @@ struct virtio_net {
        struct guest_page       *guest_pages;
 
        int                     slave_req_fd;
-} __rte_cache_aligned;
 
+       /* private data for external virtio device */
+       void                    *extern_data;
+       /* pre and post vhost user message handlers for externel backend */
+       struct vhost_user_extern_ops extern_ops;
+} __rte_cache_aligned;
 
 #define VHOST_LOG_PAGE 4096
 
diff --git a/lib/librte_vhost/vhost_user.c b/lib/librte_vhost/vhost_user.c
index 66e1b82a5..a435cce17 100644
--- a/lib/librte_vhost/vhost_user.c
+++ b/lib/librte_vhost/vhost_user.c
@@ -1,5 +1,5 @@
 /* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
+ * Copyright(c) 2010-2018 Intel Corporation
  */
 
 /* Security model
@@ -1379,6 +1379,7 @@ vhost_user_msg_handler(int vid, int fd)
        struct VhostUserMsg msg;
        int ret;
        int unlock_required = 0;
+       uint32_t skip_master = 0;
 
        dev = get_device(vid);
        if (dev == NULL)
@@ -1456,6 +1457,21 @@ vhost_user_msg_handler(int vid, int fd)
 
        }
 
+       if (dev->extern_ops.pre_msg_handle) {
+               uint32_t need_reply;
+
+               ret = (*dev->extern_ops.pre_msg_handle)(dev->vid,
+                               (void *)&msg, &need_reply, &skip_master);
+               if (ret < 0)
+                       goto skip_to_reply;
+
+               if (need_reply)
+                       send_vhost_reply(fd, &msg);
+
+               if (skip_master)
+                       goto skip_to_post_handle;
+       }
+
        switch (msg.request.master) {
        case VHOST_USER_GET_FEATURES:
                msg.payload.u64 = vhost_user_get_features(dev);
@@ -1556,9 +1572,22 @@ vhost_user_msg_handler(int vid, int fd)
        default:
                ret = -1;
                break;
+       }
+
+skip_to_post_handle:
+       if (dev->extern_ops.post_msg_handle) {
+               uint32_t need_reply;
+
+               ret = (*dev->extern_ops.post_msg_handle)(
+                               dev->vid, (void *)&msg, &need_reply);
+               if (ret < 0)
+                       goto skip_to_reply;
 
+               if (need_reply)
+                       send_vhost_reply(fd, &msg);
        }
 
+skip_to_reply:
        if (unlock_required)
                vhost_user_unlock_all_queue_pairs(dev);
 
-- 
2.13.6

Reply via email to