aboutsummaryrefslogtreecommitdiff
path: root/net.c
diff options
context:
space:
mode:
authorJan Kiszka <jan.kiszka@siemens.com>2009-06-24 14:42:31 +0200
committerAnthony Liguori <aliguori@us.ibm.com>2009-06-29 08:52:49 -0500
commitad0d8c4c326c87ee3f193f90f31ec4af0fce5598 (patch)
tree8cf29f6a524c52cdf7cc1b482060ade9e4a485e7 /net.c
parent9f8bd0421dc03b2640ac2d0a4d702354a218b2ab (diff)
slirp: Allocate/free stack instance dynamically
Allocate the internal slirp state dynamically and provide and call slirp_cleanup to properly release it after use. This patch finally unbreaks slirp release and re-instantiation via host_net_* monitor commands. Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Diffstat (limited to 'net.c')
-rw-r--r--net.c212
1 files changed, 103 insertions, 109 deletions
diff --git a/net.c b/net.c
index 3b20ba5f03..389be4a6ad 100644
--- a/net.c
+++ b/net.c
@@ -729,11 +729,13 @@ static ssize_t slirp_receive(VLANClientState *vc, const uint8_t *buf, size_t siz
return size;
}
-static int slirp_in_use;
-
static void net_slirp_cleanup(VLANClientState *vc)
{
- slirp_in_use = 0;
+ SlirpState *s = vc->opaque;
+
+ slirp_cleanup(s->slirp);
+ slirp_state = NULL;
+ qemu_free(s);
}
static int net_slirp_init(Monitor *mon, VLANState *vlan, const char *model,
@@ -744,137 +746,129 @@ static int net_slirp_init(Monitor *mon, VLANState *vlan, const char *model,
const char *vnameserver, const char *smb_export,
const char *vsmbserver)
{
- SlirpState *s = slirp_state;
-
- if (slirp_in_use) {
- /* slirp only supports a single instance so far */
- return -1;
- }
- if (!s) {
- /* default settings according to historic slirp */
- struct in_addr net = { .s_addr = htonl(0x0a000000) }; /* 10.0.0.0 */
- struct in_addr mask = { .s_addr = htonl(0xff000000) }; /* 255.0.0.0 */
- struct in_addr host = { .s_addr = htonl(0x0a000202) }; /* 10.0.2.2 */
- struct in_addr dhcp = { .s_addr = htonl(0x0a00020f) }; /* 10.0.2.15 */
- struct in_addr dns = { .s_addr = htonl(0x0a000203) }; /* 10.0.2.3 */
+ /* default settings according to historic slirp */
+ struct in_addr net = { .s_addr = htonl(0x0a000000) }; /* 10.0.0.0 */
+ struct in_addr mask = { .s_addr = htonl(0xff000000) }; /* 255.0.0.0 */
+ struct in_addr host = { .s_addr = htonl(0x0a000202) }; /* 10.0.2.2 */
+ struct in_addr dhcp = { .s_addr = htonl(0x0a00020f) }; /* 10.0.2.15 */
+ struct in_addr dns = { .s_addr = htonl(0x0a000203) }; /* 10.0.2.3 */
#ifndef _WIN32
- struct in_addr smbsrv = { .s_addr = 0 };
+ struct in_addr smbsrv = { .s_addr = 0 };
#endif
- char buf[20];
- uint32_t addr;
- int shift;
- char *end;
+ SlirpState *s;
+ char buf[20];
+ uint32_t addr;
+ int shift;
+ char *end;
- if (!tftp_export) {
- tftp_export = legacy_tftp_prefix;
- }
- if (!bootfile) {
- bootfile = legacy_bootp_filename;
- }
+ if (!tftp_export) {
+ tftp_export = legacy_tftp_prefix;
+ }
+ if (!bootfile) {
+ bootfile = legacy_bootp_filename;
+ }
- if (vnetwork) {
- if (get_str_sep(buf, sizeof(buf), &vnetwork, '/') < 0) {
- if (!inet_aton(vnetwork, &net)) {
- return -1;
- }
- addr = ntohl(net.s_addr);
- if (!(addr & 0x80000000)) {
- mask.s_addr = htonl(0xff000000); /* class A */
- } else if ((addr & 0xfff00000) == 0xac100000) {
- mask.s_addr = htonl(0xfff00000); /* priv. 172.16.0.0/12 */
- } else if ((addr & 0xc0000000) == 0x80000000) {
- mask.s_addr = htonl(0xffff0000); /* class B */
- } else if ((addr & 0xffff0000) == 0xc0a80000) {
- mask.s_addr = htonl(0xffff0000); /* priv. 192.168.0.0/16 */
- } else if ((addr & 0xffff0000) == 0xc6120000) {
- mask.s_addr = htonl(0xfffe0000); /* tests 198.18.0.0/15 */
- } else if ((addr & 0xe0000000) == 0xe0000000) {
- mask.s_addr = htonl(0xffffff00); /* class C */
- } else {
- mask.s_addr = htonl(0xfffffff0); /* multicast/reserved */
- }
+ if (vnetwork) {
+ if (get_str_sep(buf, sizeof(buf), &vnetwork, '/') < 0) {
+ if (!inet_aton(vnetwork, &net)) {
+ return -1;
+ }
+ addr = ntohl(net.s_addr);
+ if (!(addr & 0x80000000)) {
+ mask.s_addr = htonl(0xff000000); /* class A */
+ } else if ((addr & 0xfff00000) == 0xac100000) {
+ mask.s_addr = htonl(0xfff00000); /* priv. 172.16.0.0/12 */
+ } else if ((addr & 0xc0000000) == 0x80000000) {
+ mask.s_addr = htonl(0xffff0000); /* class B */
+ } else if ((addr & 0xffff0000) == 0xc0a80000) {
+ mask.s_addr = htonl(0xffff0000); /* priv. 192.168.0.0/16 */
+ } else if ((addr & 0xffff0000) == 0xc6120000) {
+ mask.s_addr = htonl(0xfffe0000); /* tests 198.18.0.0/15 */
+ } else if ((addr & 0xe0000000) == 0xe0000000) {
+ mask.s_addr = htonl(0xffffff00); /* class C */
} else {
- if (!inet_aton(buf, &net)) {
- return -1;
- }
- shift = strtol(vnetwork, &end, 10);
- if (*end != '\0') {
- if (!inet_aton(vnetwork, &mask)) {
- return -1;
- }
- } else if (shift < 4 || shift > 32) {
+ mask.s_addr = htonl(0xfffffff0); /* multicast/reserved */
+ }
+ } else {
+ if (!inet_aton(buf, &net)) {
+ return -1;
+ }
+ shift = strtol(vnetwork, &end, 10);
+ if (*end != '\0') {
+ if (!inet_aton(vnetwork, &mask)) {
return -1;
- } else {
- mask.s_addr = htonl(0xffffffff << (32 - shift));
}
+ } else if (shift < 4 || shift > 32) {
+ return -1;
+ } else {
+ mask.s_addr = htonl(0xffffffff << (32 - shift));
}
- net.s_addr &= mask.s_addr;
- host.s_addr = net.s_addr | (htonl(0x0202) & ~mask.s_addr);
- dhcp.s_addr = net.s_addr | (htonl(0x020f) & ~mask.s_addr);
- dns.s_addr = net.s_addr | (htonl(0x0203) & ~mask.s_addr);
}
+ net.s_addr &= mask.s_addr;
+ host.s_addr = net.s_addr | (htonl(0x0202) & ~mask.s_addr);
+ dhcp.s_addr = net.s_addr | (htonl(0x020f) & ~mask.s_addr);
+ dns.s_addr = net.s_addr | (htonl(0x0203) & ~mask.s_addr);
+ }
- if (vhost && !inet_aton(vhost, &host)) {
- return -1;
- }
- if ((host.s_addr & mask.s_addr) != net.s_addr) {
- return -1;
- }
+ if (vhost && !inet_aton(vhost, &host)) {
+ return -1;
+ }
+ if ((host.s_addr & mask.s_addr) != net.s_addr) {
+ return -1;
+ }
- if (vdhcp_start && !inet_aton(vdhcp_start, &dhcp)) {
- return -1;
- }
- if ((dhcp.s_addr & mask.s_addr) != net.s_addr ||
- dhcp.s_addr == host.s_addr || dhcp.s_addr == dns.s_addr) {
- return -1;
- }
+ if (vdhcp_start && !inet_aton(vdhcp_start, &dhcp)) {
+ return -1;
+ }
+ if ((dhcp.s_addr & mask.s_addr) != net.s_addr ||
+ dhcp.s_addr == host.s_addr || dhcp.s_addr == dns.s_addr) {
+ return -1;
+ }
- if (vnameserver && !inet_aton(vnameserver, &dns)) {
- return -1;
- }
- if ((dns.s_addr & mask.s_addr) != net.s_addr ||
- dns.s_addr == host.s_addr) {
- return -1;
- }
+ if (vnameserver && !inet_aton(vnameserver, &dns)) {
+ return -1;
+ }
+ if ((dns.s_addr & mask.s_addr) != net.s_addr ||
+ dns.s_addr == host.s_addr) {
+ return -1;
+ }
#ifndef _WIN32
- if (vsmbserver && !inet_aton(vsmbserver, &smbsrv)) {
- return -1;
- }
+ if (vsmbserver && !inet_aton(vsmbserver, &smbsrv)) {
+ return -1;
+ }
#endif
- s = qemu_mallocz(sizeof(SlirpState));
- s->slirp = slirp_init(restricted, net, mask, host, vhostname,
- tftp_export, bootfile, dhcp, dns, s);
- slirp_state = s;
+ s = qemu_mallocz(sizeof(SlirpState));
+ s->slirp = slirp_init(restricted, net, mask, host, vhostname,
+ tftp_export, bootfile, dhcp, dns, s);
+ slirp_state = s;
- while (slirp_configs) {
- struct slirp_config_str *config = slirp_configs;
+ while (slirp_configs) {
+ struct slirp_config_str *config = slirp_configs;
- if (config->flags & SLIRP_CFG_HOSTFWD) {
- slirp_hostfwd(s, mon, config->str,
- config->flags & SLIRP_CFG_LEGACY);
- } else {
- slirp_guestfwd(s, mon, config->str,
- config->flags & SLIRP_CFG_LEGACY);
- }
- slirp_configs = config->next;
- qemu_free(config);
+ if (config->flags & SLIRP_CFG_HOSTFWD) {
+ slirp_hostfwd(s, mon, config->str,
+ config->flags & SLIRP_CFG_LEGACY);
+ } else {
+ slirp_guestfwd(s, mon, config->str,
+ config->flags & SLIRP_CFG_LEGACY);
}
+ slirp_configs = config->next;
+ qemu_free(config);
+ }
#ifndef _WIN32
- if (!smb_export) {
- smb_export = legacy_smb_export;
- }
- if (smb_export) {
- slirp_smb(s, smb_export, smbsrv);
- }
-#endif
+ if (!smb_export) {
+ smb_export = legacy_smb_export;
+ }
+ if (smb_export) {
+ slirp_smb(s, smb_export, smbsrv);
}
+#endif
s->vc = qemu_new_vlan_client(vlan, model, name, NULL, slirp_receive, NULL,
net_slirp_cleanup, s);
s->vc->info_str[0] = '\0';
- slirp_in_use = 1;
return 0;
}