diff options
author | Laszlo Ersek <lersek@redhat.com> | 2012-07-17 16:17:17 +0200 |
---|---|---|
committer | Stefan Hajnoczi <stefanha@linux.vnet.ibm.com> | 2012-07-23 11:55:18 +0100 |
commit | bef8e8fe07e80821992f61d3775c6ac3766eee48 (patch) | |
tree | 3296361f99feef37c1b0432f5981c4105ee8577a /net/socket.c | |
parent | 094f15c5c80a835dbe69afa8534909c681d35856 (diff) |
convert net_init_socket() to NetClientOptions
I "reverse engineered" the following permissions between the -socket
sub-options:
fd listen connect mcast udp | localaddr
fd x . . . . | .
listen . x . . . | .
connect . . x . . | .
mcast . . . x . | x
udp . . . . x | x
-------------------------------------------+
localaddr . . . x x x
I transformed the code accordingly. The real fix would be to embed "fd",
"listen", "connect", "mcast" and "udp" in a separate union. However
OptsVisitor's enum parser only supports the type=XXX QemuOpt instance as
union discriminator.
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Diffstat (limited to 'net/socket.c')
-rw-r--r-- | net/socket.c | 119 |
1 files changed, 43 insertions, 76 deletions
diff --git a/net/socket.c b/net/socket.c index 563447d02e..e3cba20cd9 100644 --- a/net/socket.c +++ b/net/socket.c @@ -586,101 +586,68 @@ static int net_socket_udp_init(VLANState *vlan, return 0; } -int net_init_socket(QemuOpts *opts, const NetClientOptions *new_opts, +int net_init_socket(QemuOpts *old_opts, const NetClientOptions *opts, const char *name, VLANState *vlan) { - if (qemu_opt_get(opts, "fd")) { - int fd; + const NetdevSocketOptions *sock; - if (qemu_opt_get(opts, "listen") || - qemu_opt_get(opts, "connect") || - qemu_opt_get(opts, "mcast") || - qemu_opt_get(opts, "localaddr")) { - error_report("listen=, connect=, mcast= and localaddr= is invalid with fd="); - return -1; - } + assert(opts->kind == NET_CLIENT_OPTIONS_KIND_SOCKET); + sock = opts->socket; - fd = net_handle_fd_param(cur_mon, qemu_opt_get(opts, "fd")); - if (fd == -1) { - return -1; - } + if (sock->has_fd + sock->has_listen + sock->has_connect + sock->has_mcast + + sock->has_udp != 1) { + error_report("exactly one of fd=, listen=, connect=, mcast= or udp=" + " is required"); + return -1; + } - if (!net_socket_fd_init(vlan, "socket", name, fd, 1)) { - return -1; - } - } else if (qemu_opt_get(opts, "listen")) { - const char *listen; - - if (qemu_opt_get(opts, "fd") || - qemu_opt_get(opts, "connect") || - qemu_opt_get(opts, "mcast") || - qemu_opt_get(opts, "localaddr")) { - error_report("fd=, connect=, mcast= and localaddr= is invalid with listen="); - return -1; - } + if (sock->has_localaddr && !sock->has_mcast && !sock->has_udp) { + error_report("localaddr= is only valid with mcast= or udp="); + return -1; + } - listen = qemu_opt_get(opts, "listen"); + if (sock->has_fd) { + int fd; - if (net_socket_listen_init(vlan, "socket", name, listen) == -1) { - return -1; - } - } else if (qemu_opt_get(opts, "connect")) { - const char *connect; - - if (qemu_opt_get(opts, "fd") || - qemu_opt_get(opts, "listen") || - qemu_opt_get(opts, "mcast") || - qemu_opt_get(opts, "localaddr")) { - error_report("fd=, listen=, mcast= and localaddr= is invalid with connect="); + fd = net_handle_fd_param(cur_mon, sock->fd); + if (fd == -1 || !net_socket_fd_init(vlan, "socket", name, fd, 1)) { return -1; } + return 0; + } - connect = qemu_opt_get(opts, "connect"); - - if (net_socket_connect_init(vlan, "socket", name, connect) == -1) { + if (sock->has_listen) { + if (net_socket_listen_init(vlan, "socket", name, sock->listen) == -1) { return -1; } - } else if (qemu_opt_get(opts, "mcast")) { - const char *mcast, *localaddr; + return 0; + } - if (qemu_opt_get(opts, "fd") || - qemu_opt_get(opts, "connect") || - qemu_opt_get(opts, "listen")) { - error_report("fd=, connect= and listen= is invalid with mcast="); + if (sock->has_connect) { + if (net_socket_connect_init(vlan, "socket", name, sock->connect) == + -1) { return -1; } + return 0; + } - mcast = qemu_opt_get(opts, "mcast"); - localaddr = qemu_opt_get(opts, "localaddr"); - - if (net_socket_mcast_init(vlan, "socket", name, mcast, localaddr) == -1) { - return -1; - } - } else if (qemu_opt_get(opts, "udp")) { - const char *udp, *localaddr; - - if (qemu_opt_get(opts, "fd") || - qemu_opt_get(opts, "connect") || - qemu_opt_get(opts, "listen") || - qemu_opt_get(opts, "mcast")) { - error_report("fd=, connect=, listen=" - " and mcast= is invalid with udp="); + if (sock->has_mcast) { + /* if sock->localaddr is missing, it has been initialized to "all bits + * zero" */ + if (net_socket_mcast_init(vlan, "socket", name, sock->mcast, + sock->localaddr) == -1) { return -1; } + return 0; + } - udp = qemu_opt_get(opts, "udp"); - localaddr = qemu_opt_get(opts, "localaddr"); - if (localaddr == NULL) { - error_report("localaddr= is mandatory with udp="); - return -1; - } - - if (net_socket_udp_init(vlan, "udp", name, udp, localaddr) == -1) { - return -1; - } - } else { - error_report("-socket requires fd=, listen=," - " connect=, mcast= or udp="); + assert(sock->has_udp); + if (!sock->has_localaddr) { + error_report("localaddr= is mandatory with udp="); + return -1; + } + if (net_socket_udp_init(vlan, "udp", name, sock->udp, sock->localaddr) == + -1) { return -1; } return 0; |