qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 33/41] slirp: Allocate/free stack instance dynamical


From: Jan Kiszka
Subject: [Qemu-devel] [PATCH 33/41] slirp: Allocate/free stack instance dynamically
Date: Wed, 24 Jun 2009 14:42:31 +0200
User-agent: StGIT/0.14.3

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 <address@hidden>
---

 net.c            |  212 ++++++++++++++++++++++++++----------------------------
 slirp/libslirp.h |    1 
 slirp/main.h     |    1 
 slirp/slirp.c    |   32 +++++---
 slirp/slirp.h    |    2 -
 5 files changed, 124 insertions(+), 124 deletions(-)

diff --git a/net.c b/net.c
index 5a4791b..0c58124 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;
 }
 
diff --git a/slirp/libslirp.h b/slirp/libslirp.h
index 521de3e..3bcc392 100644
--- a/slirp/libslirp.h
+++ b/slirp/libslirp.h
@@ -13,6 +13,7 @@ Slirp *slirp_init(int restricted, struct in_addr vnetwork,
                   const char *vhostname, const char *tftp_path,
                   const char *bootfile, struct in_addr vdhcp_start,
                   struct in_addr vnameserver, void *opaque);
+void slirp_cleanup(Slirp *slirp);
 
 void slirp_select_fill(int *pnfds,
                        fd_set *readfds, fd_set *writefds, fd_set *xfds);
diff --git a/slirp/main.h b/slirp/main.h
index 90deb58..28d92d8 100644
--- a/slirp/main.h
+++ b/slirp/main.h
@@ -11,7 +11,6 @@
 
 #define TOWRITEMAX 512
 
-extern int link_up;
 extern int slirp_socket;
 extern int slirp_socket_unit;
 extern int slirp_socket_port;
diff --git a/slirp/slirp.c b/slirp/slirp.c
index 7e86124..43aba3d 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -40,8 +40,6 @@ static const uint8_t special_ethaddr[6] = {
 
 static const uint8_t zero_ethaddr[6] = { 0, 0, 0, 0, 0, 0 };
 
-int link_up; // FIXME: kill this
-
 /* XXX: suppress those select globals */
 fd_set *global_readfds, *global_writefds, *global_xfds;
 
@@ -49,7 +47,7 @@ u_int curtime;
 static u_int time_fasttimo, last_slowtimo;
 static int do_slowtimo;
 
-Slirp slirp_instance;
+Slirp *slirp_instance;
 
 #ifdef _WIN32
 
@@ -193,11 +191,10 @@ Slirp *slirp_init(int restricted, struct in_addr vnetwork,
                   const char *bootfile, struct in_addr vdhcp_start,
                   struct in_addr vnameserver, void *opaque)
 {
-    Slirp *slirp = &slirp_instance;
+    Slirp *slirp = qemu_mallocz(sizeof(Slirp));
 
     slirp_init_once();
 
-    link_up = 1;
     slirp->restricted = restricted;
 
     if_init(slirp);
@@ -213,13 +210,9 @@ Slirp *slirp_init(int restricted, struct in_addr vnetwork,
         pstrcpy(slirp->client_hostname, sizeof(slirp->client_hostname),
                 vhostname);
     }
-    qemu_free(slirp->tftp_prefix);
-    slirp->tftp_prefix = NULL;
     if (tftp_path) {
         slirp->tftp_prefix = qemu_strdup(tftp_path);
     }
-    qemu_free(slirp->bootp_filename);
-    slirp->bootp_filename = NULL;
     if (bootfile) {
         slirp->bootp_filename = qemu_strdup(bootfile);
     }
@@ -230,9 +223,22 @@ Slirp *slirp_init(int restricted, struct in_addr vnetwork,
 
     register_savevm("slirp", 0, 2, slirp_state_save, slirp_state_load, slirp);
 
+    slirp_instance = slirp;
+
     return slirp;
 }
 
+void slirp_cleanup(Slirp *slirp)
+{
+    unregister_savevm("slirp", slirp);
+
+    qemu_free(slirp->tftp_prefix);
+    qemu_free(slirp->bootp_filename);
+    qemu_free(slirp);
+
+    slirp_instance = NULL;
+}
+
 #define CONN_CANFSEND(so) (((so)->so_state & 
(SS_FCANTSENDMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED)
 #define CONN_CANFRCV(so) (((so)->so_state & (SS_FCANTRCVMORE|SS_ISFCONNECTED)) 
== SS_ISFCONNECTED)
 #define UPD_NFDS(x) if (nfds < (x)) nfds = (x)
@@ -263,11 +269,11 @@ static void updtime(void)
 void slirp_select_fill(int *pnfds,
                        fd_set *readfds, fd_set *writefds, fd_set *xfds)
 {
-    Slirp *slirp = &slirp_instance;
+    Slirp *slirp = slirp_instance;
     struct socket *so, *so_next;
     int nfds;
 
-    if (!link_up) {
+    if (!slirp_instance) {
         return;
     }
 
@@ -384,11 +390,11 @@ void slirp_select_fill(int *pnfds,
 void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds,
                        int select_error)
 {
-    Slirp *slirp = &slirp_instance;
+    Slirp *slirp = slirp_instance;
     struct socket *so, *so_next;
     int ret;
 
-    if (!link_up) {
+    if (!slirp_instance) {
         return;
     }
 
diff --git a/slirp/slirp.h b/slirp/slirp.h
index cb1a746..5d8861c 100644
--- a/slirp/slirp.h
+++ b/slirp/slirp.h
@@ -259,7 +259,7 @@ struct Slirp {
     void *opaque;
 };
 
-extern Slirp slirp_instance;
+extern Slirp *slirp_instance;
 
 #ifndef NULL
 #define NULL (void *)0





reply via email to

[Prev in Thread] Current Thread [Next in Thread]