[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v2 for-3.2 v2 07/30] slirp: generalize guestfwd with
From: |
Marc-André Lureau |
Subject: |
[Qemu-devel] [PATCH v2 for-3.2 v2 07/30] slirp: generalize guestfwd with a callback based approach |
Date: |
Thu, 22 Nov 2018 02:06:24 +0400 |
Instead of calling into QEMU chardev directly, and mixing it with
slirp_add_exec() handling, add a new function slirp_add_guestfwd()
which takes a write callback.
Signed-off-by: Marc-André Lureau <address@hidden>
---
slirp/libslirp.h | 6 +++++-
slirp/misc.h | 15 +++++++++++++--
slirp/socket.h | 4 +++-
net/slirp.c | 14 ++++++++++----
slirp/misc.c | 37 +++++++++++++++++++++++--------------
slirp/slirp.c | 27 +++++++++++++++++++--------
slirp/tcp_subr.c | 4 ++--
7 files changed, 75 insertions(+), 32 deletions(-)
diff --git a/slirp/libslirp.h b/slirp/libslirp.h
index 3e0aa19f4b..d7c2b1ae71 100644
--- a/slirp/libslirp.h
+++ b/slirp/libslirp.h
@@ -5,6 +5,8 @@
typedef struct Slirp Slirp;
+typedef int (*SlirpWriteCb)(const void *buf, size_t len, void *opaque);
+
/*
* Callbacks from slirp
*
@@ -43,7 +45,9 @@ int slirp_add_hostfwd(Slirp *slirp, int is_udp,
struct in_addr guest_addr, int guest_port);
int slirp_remove_hostfwd(Slirp *slirp, int is_udp,
struct in_addr host_addr, int host_port);
-int slirp_add_exec(Slirp *slirp, void *chardev, const char *cmdline,
+int slirp_add_exec(Slirp *slirp, const char *cmdline,
+ struct in_addr *guest_addr, int guest_port);
+int slirp_add_guestfwd(Slirp *slirp, SlirpWriteCb write_cb, void *opaque,
struct in_addr *guest_addr, int guest_port);
char *slirp_connection_info(Slirp *slirp);
diff --git a/slirp/misc.h b/slirp/misc.h
index 1df707c052..c2ceadb591 100644
--- a/slirp/misc.h
+++ b/slirp/misc.h
@@ -8,8 +8,11 @@
#ifndef MISC_H
#define MISC_H
+#include "libslirp.h"
+
struct gfwd_list {
- void *ex_chardev;
+ SlirpWriteCb write_cb;
+ void *opaque;
struct in_addr ex_addr; /* Server address */
int ex_fport; /* Port to telnet to */
char *ex_exec; /* Command line of what to exec */
@@ -51,7 +54,15 @@ struct slirp_quehead {
void slirp_insque(void *, void *);
void slirp_remque(void *);
-int add_exec(struct gfwd_list **, void *, const char *, struct in_addr, int);
int fork_exec(struct socket *so, const char *ex);
+struct gfwd_list *
+add_guestfwd(struct gfwd_list **ex_ptr,
+ SlirpWriteCb write_cb, void *opaque,
+ struct in_addr addr, int port);
+
+struct gfwd_list *
+add_exec(struct gfwd_list **ex_ptr, const char *cmdline,
+ struct in_addr addr, int port);
+
#endif
diff --git a/slirp/socket.h b/slirp/socket.h
index 930ed95972..fc35ca5f72 100644
--- a/slirp/socket.h
+++ b/slirp/socket.h
@@ -8,6 +8,8 @@
#ifndef SLIRP_SOCKET_H
#define SLIRP_SOCKET_H
+#include "misc.h"
+
#define SO_EXPIRE 240000
#define SO_EXPIREFAST 10000
@@ -25,6 +27,7 @@ struct socket {
struct socket *so_next,*so_prev; /* For a linked list of sockets */
int s; /* The actual socket */
+ struct gfwd_list *guestfwd;
int pollfds_idx; /* GPollFD GArray index */
@@ -67,7 +70,6 @@ struct socket {
struct sbuf so_rcv; /* Receive buffer */
struct sbuf so_snd; /* Send buffer */
- void * chardev;
};
diff --git a/net/slirp.c b/net/slirp.c
index 4d890287ba..53adb92dd5 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -698,8 +698,8 @@ static int slirp_smb(SlirpState* s, const char
*exported_dir,
CONFIG_SMBD_COMMAND, s->smb_dir, smb_conf);
g_free(smb_conf);
- if (slirp_add_exec(s->slirp, NULL, smb_cmdline, &vserver_addr, 139) < 0 ||
- slirp_add_exec(s->slirp, NULL, smb_cmdline, &vserver_addr, 445) < 0) {
+ if (slirp_add_exec(s->slirp, smb_cmdline, &vserver_addr, 139) < 0 ||
+ slirp_add_exec(s->slirp, smb_cmdline, &vserver_addr, 445) < 0) {
slirp_smb_cleanup(s);
g_free(smb_cmdline);
error_setg(errp, "Conflicting/invalid smbserver address");
@@ -730,6 +730,11 @@ static void guestfwd_read(void *opaque, const uint8_t
*buf, int size)
slirp_socket_recv(fwd->slirp, fwd->server, fwd->port, buf, size);
}
+static int guestfwd_write(const void *buf, size_t len, void *chr)
+{
+ return qemu_chr_fe_write_all(chr, buf, len);
+}
+
static int slirp_guestfwd(SlirpState *s, const char *config_str, Error **errp)
{
struct in_addr server = { .s_addr = 0 };
@@ -763,7 +768,7 @@ static int slirp_guestfwd(SlirpState *s, const char
*config_str, Error **errp)
snprintf(buf, sizeof(buf), "guestfwd.tcp.%d", port);
if ((strlen(p) > 4) && !strncmp(p, "cmd:", 4)) {
- if (slirp_add_exec(s->slirp, NULL, &p[4], &server, port) < 0) {
+ if (slirp_add_exec(s->slirp, &p[4], &server, port) < 0) {
error_setg(errp, "Conflicting/invalid host:port in guest "
"forwarding rule '%s'", config_str);
return -1;
@@ -790,7 +795,8 @@ static int slirp_guestfwd(SlirpState *s, const char
*config_str, Error **errp)
return -1;
}
- if (slirp_add_exec(s->slirp, &fwd->hd, NULL, &server, port) < 0) {
+ if (slirp_add_guestfwd(s->slirp, guestfwd_write, &fwd->hd,
+ &server, port) < 0) {
error_setg(errp, "Conflicting/invalid host:port in guest "
"forwarding rule '%s'", config_str);
g_free(fwd);
diff --git a/slirp/misc.c b/slirp/misc.c
index 03bfa31f20..7c2ed8c67f 100644
--- a/slirp/misc.c
+++ b/slirp/misc.c
@@ -36,24 +36,33 @@ remque(void *a)
element->qh_rlink = NULL;
}
-int add_exec(struct gfwd_list **ex_ptr, void *chardev, const char *cmdline,
+struct gfwd_list *
+add_guestfwd(struct gfwd_list **ex_ptr,
+ SlirpWriteCb write_cb, void *opaque,
struct in_addr addr, int port)
{
- struct gfwd_list *tmp_ptr;
-
- tmp_ptr = *ex_ptr;
- *ex_ptr = g_new0(struct gfwd_list, 1);
- (*ex_ptr)->ex_fport = port;
- (*ex_ptr)->ex_addr = addr;
- if (chardev) {
- (*ex_ptr)->ex_chardev = chardev;
- } else {
- (*ex_ptr)->ex_exec = g_strdup(cmdline);
- }
- (*ex_ptr)->ex_next = tmp_ptr;
- return 0;
+ struct gfwd_list *f = g_new0(struct gfwd_list, 1);
+
+ f->write_cb = write_cb;
+ f->opaque = opaque;
+ f->ex_fport = port;
+ f->ex_addr = addr;
+ f->ex_next = *ex_ptr;
+ *ex_ptr = f;
+
+ return f;
}
+struct gfwd_list *
+add_exec(struct gfwd_list **ex_ptr, const char *cmdline,
+ struct in_addr addr, int port)
+{
+ struct gfwd_list *f = add_guestfwd(ex_ptr, NULL, NULL, addr, port);
+
+ f->ex_exec = g_strdup(cmdline);
+
+ return f;
+}
#ifdef _WIN32
diff --git a/slirp/slirp.c b/slirp/slirp.c
index e7256ec05c..cc361885ed 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -25,7 +25,6 @@
#include "qemu-common.h"
#include "qemu/timer.h"
#include "qemu/error-report.h"
-#include "chardev/char-fe.h"
#include "migration/register.h"
#include "slirp.h"
#include "hw/hw.h"
@@ -1064,23 +1063,35 @@ check_guestfwd(Slirp *slirp, struct in_addr
*guest_addr, int guest_port)
return true;
}
-int slirp_add_exec(Slirp *slirp, void *chardev, const char *cmdline,
+int slirp_add_exec(Slirp *slirp, const char *cmdline,
struct in_addr *guest_addr, int guest_port)
{
if (!check_guestfwd(slirp, guest_addr, guest_port)) {
return -1;
}
- return add_exec(&slirp->guestfwd_list, chardev, cmdline, *guest_addr,
- htons(guest_port));
+ add_exec(&slirp->guestfwd_list, cmdline, *guest_addr, htons(guest_port));
+ return 0;
+}
+
+int slirp_add_guestfwd(Slirp *slirp, SlirpWriteCb write_cb, void *opaque,
+ struct in_addr *guest_addr, int guest_port)
+{
+ if (!check_guestfwd(slirp, guest_addr, guest_port)) {
+ return -1;
+ }
+
+ add_guestfwd(&slirp->guestfwd_list, write_cb, opaque,
+ *guest_addr, htons(guest_port));
+ return 0;
}
ssize_t slirp_send(struct socket *so, const void *buf, size_t len, int flags)
{
- if (so->s == -1 && so->chardev) {
+ if (so->s == -1 && so->guestfwd) {
/* XXX this blocks entire thread. Rewrite to use
* qemu_chr_fe_write and background I/O callbacks */
- qemu_chr_fe_write_all(so->chardev, buf, len);
+ so->guestfwd->write_cb(buf, len, so->guestfwd->opaque);
return len;
}
@@ -1445,7 +1456,7 @@ static void slirp_state_save(QEMUFile *f, void *opaque)
struct gfwd_list *ex_ptr;
for (ex_ptr = slirp->guestfwd_list; ex_ptr; ex_ptr = ex_ptr->ex_next)
- if (ex_ptr->ex_chardev) {
+ if (ex_ptr->write_cb) {
struct socket *so;
so = slirp_find_ctl_socket(slirp, ex_ptr->ex_addr,
ntohs(ex_ptr->ex_fport));
@@ -1480,7 +1491,7 @@ static int slirp_state_load(QEMUFile *f, void *opaque,
int version_id)
return -EINVAL;
}
for (ex_ptr = slirp->guestfwd_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
- if (ex_ptr->ex_chardev &&
+ if (ex_ptr->write_cb &&
so->so_faddr.s_addr == ex_ptr->ex_addr.s_addr &&
so->so_fport == ex_ptr->ex_fport) {
break;
diff --git a/slirp/tcp_subr.c b/slirp/tcp_subr.c
index 3b14684107..042fa1e4fb 100644
--- a/slirp/tcp_subr.c
+++ b/slirp/tcp_subr.c
@@ -959,9 +959,9 @@ int tcp_ctl(struct socket *so)
for (ex_ptr = slirp->guestfwd_list; ex_ptr; ex_ptr = ex_ptr->ex_next) {
if (ex_ptr->ex_fport == so->so_fport &&
so->so_faddr.s_addr == ex_ptr->ex_addr.s_addr) {
- if (ex_ptr->ex_chardev) {
+ if (ex_ptr->write_cb) {
so->s = -1;
- so->chardev = ex_ptr->ex_chardev;
+ so->guestfwd = ex_ptr;
return 1;
}
DEBUG_MISC(" executing %s\n", ex_ptr->ex_exec);
--
2.20.0.rc1
- [Qemu-devel] [PATCH v2 for-3.2 v2 02/30] slirp: drop <Vista compatibility, (continued)
- [Qemu-devel] [PATCH v2 for-3.2 v2 02/30] slirp: drop <Vista compatibility, Marc-André Lureau, 2018/11/21
- [Qemu-devel] [PATCH v2 for-3.2 v2 03/30] glib-compat: add g_spawn_async_with_fds() fallback, Marc-André Lureau, 2018/11/21
- [Qemu-devel] [PATCH v2 for-3.2 v2 04/30] slirp: simplify fork_exec(), Marc-André Lureau, 2018/11/21
- [Qemu-devel] [PATCH v2 for-3.2 v2 05/30] slirp: rename exec_list, Marc-André Lureau, 2018/11/21
- [Qemu-devel] [PATCH v2 for-3.2 v2 06/30] slirp: factor out guestfwd addition checks, Marc-André Lureau, 2018/11/21
- [Qemu-devel] [PATCH v2 for-3.2 v2 07/30] slirp: generalize guestfwd with a callback based approach,
Marc-André Lureau <=
- [Qemu-devel] [PATCH v2 for-3.2 v2 08/30] net/slirp: simplify checking for cmd: prefix, Marc-André Lureau, 2018/11/21
- [Qemu-devel] [PATCH v2 for-3.2 v2 09/30] net/slirp: fix a few memory leaks, Marc-André Lureau, 2018/11/21
- [Qemu-devel] [PATCH v2 for-3.2 v2 10/30] slirp: use virtual time for packet expiration, Marc-André Lureau, 2018/11/21
- [Qemu-devel] [PATCH v2 for-3.2 v2 11/30] slirp: add clock_get_ns() callback, Marc-André Lureau, 2018/11/21
- [Qemu-devel] [PATCH v2 for-3.2 v2 12/30] slirp: add callbacks for timer, Marc-André Lureau, 2018/11/21
- [Qemu-devel] [PATCH v2 for-3.2 v2 13/30] build-sys: use a seperate slirp-obj-y && slirp.mo, Marc-André Lureau, 2018/11/21
- [Qemu-devel] [PATCH v2 for-3.2 v2 14/30] slirp: set G_LOG_DOMAIN, Marc-André Lureau, 2018/11/21