diff options
author | Jan Kiszka <jan.kiszka@siemens.com> | 2009-06-24 14:42:31 +0200 |
---|---|---|
committer | Anthony Liguori <aliguori@us.ibm.com> | 2009-06-29 08:52:49 -0500 |
commit | ad0d8c4c326c87ee3f193f90f31ec4af0fce5598 (patch) | |
tree | 8cf29f6a524c52cdf7cc1b482060ade9e4a485e7 /net.c | |
parent | 9f8bd0421dc03b2640ac2d0a4d702354a218b2ab (diff) | |
download | qemu-ad0d8c4c326c87ee3f193f90f31ec4af0fce5598.zip qemu-ad0d8c4c326c87ee3f193f90f31ec4af0fce5598.tar.gz qemu-ad0d8c4c326c87ee3f193f90f31ec4af0fce5598.tar.bz2 |
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.c | 212 |
1 files changed, 103 insertions, 109 deletions
@@ -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; } |