From a68adc220603baffc355ecea8865b3ea9707ab00 Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Wed, 29 Feb 2012 19:14:23 +0100 Subject: [PATCH] slirp: Cleanup resources on instance removal Close & free sockets when shutting down a slirp instance, also release all buffers. CC: Michael S. Tsirkin Signed-off-by: Jan Kiszka --- slirp/ip_icmp.c | 7 +++++++ slirp/ip_icmp.h | 1 + slirp/ip_input.c | 7 +++++++ slirp/mbuf.c | 21 +++++++++++++++++++++ slirp/mbuf.h | 1 + slirp/slirp.c | 3 +++ slirp/slirp.h | 2 ++ slirp/tcp_subr.c | 7 +++++++ slirp/udp.c | 8 ++++++++ slirp/udp.h | 1 + 10 files changed, 58 insertions(+) diff --git a/slirp/ip_icmp.c b/slirp/ip_icmp.c index 5dbf21da9d..d571fd0b76 100644 --- a/slirp/ip_icmp.c +++ b/slirp/ip_icmp.c @@ -66,6 +66,13 @@ void icmp_init(Slirp *slirp) slirp->icmp_last_so = &slirp->icmp; } +void icmp_cleanup(Slirp *slirp) +{ + while (slirp->icmp.so_next != &slirp->icmp) { + icmp_detach(slirp->icmp.so_next); + } +} + static int icmp_send(struct socket *so, struct mbuf *m, int hlen) { struct ip *ip = mtod(m, struct ip *); diff --git a/slirp/ip_icmp.h b/slirp/ip_icmp.h index b3da1f2697..1a1af91e1e 100644 --- a/slirp/ip_icmp.h +++ b/slirp/ip_icmp.h @@ -154,6 +154,7 @@ struct icmp { (type) == ICMP_MASKREQ || (type) == ICMP_MASKREPLY) void icmp_init(Slirp *slirp); +void icmp_cleanup(Slirp *slirp); void icmp_input(struct mbuf *, int); void icmp_error(struct mbuf *msrc, u_char type, u_char code, int minsize, const char *message); diff --git a/slirp/ip_input.c b/slirp/ip_input.c index c7b3eb4806..ce24faf165 100644 --- a/slirp/ip_input.c +++ b/slirp/ip_input.c @@ -61,6 +61,13 @@ ip_init(Slirp *slirp) icmp_init(slirp); } +void ip_cleanup(Slirp *slirp) +{ + udp_cleanup(slirp); + tcp_cleanup(slirp); + icmp_cleanup(slirp); +} + /* * Ip input routine. Checksum and byte swap header. If fragmented * try to reassemble. Process options. Pass to next level. diff --git a/slirp/mbuf.c b/slirp/mbuf.c index c699c75096..4fefb043bf 100644 --- a/slirp/mbuf.c +++ b/slirp/mbuf.c @@ -32,6 +32,27 @@ m_init(Slirp *slirp) slirp->m_usedlist.m_next = slirp->m_usedlist.m_prev = &slirp->m_usedlist; } +void m_cleanup(Slirp *slirp) +{ + struct mbuf *m, *next; + + m = slirp->m_usedlist.m_next; + while (m != &slirp->m_usedlist) { + next = m->m_next; + if (m->m_flags & M_EXT) { + free(m->m_ext); + } + free(m); + m = next; + } + m = slirp->m_freelist.m_next; + while (m != &slirp->m_freelist) { + next = m->m_next; + free(m); + m = next; + } +} + /* * Get an mbuf from the free list, if there are none * malloc one diff --git a/slirp/mbuf.h b/slirp/mbuf.h index 8d7951fb42..3f3ab095b1 100644 --- a/slirp/mbuf.h +++ b/slirp/mbuf.h @@ -116,6 +116,7 @@ struct mbuf { * it rather than putting it on the free list */ void m_init(Slirp *); +void m_cleanup(Slirp *slirp); struct mbuf * m_get(Slirp *); void m_free(struct mbuf *); void m_cat(register struct mbuf *, register struct mbuf *); diff --git a/slirp/slirp.c b/slirp/slirp.c index bcffc3414f..1502830978 100644 --- a/slirp/slirp.c +++ b/slirp/slirp.c @@ -246,6 +246,9 @@ void slirp_cleanup(Slirp *slirp) unregister_savevm(NULL, "slirp", slirp); + ip_cleanup(slirp); + m_cleanup(slirp); + g_free(slirp->tftp_prefix); g_free(slirp->bootp_filename); g_free(slirp); diff --git a/slirp/slirp.h b/slirp/slirp.h index cbe8a3cd4d..5033ee3118 100644 --- a/slirp/slirp.h +++ b/slirp/slirp.h @@ -315,6 +315,7 @@ void if_output(struct socket *, struct mbuf *); /* ip_input.c */ void ip_init(Slirp *); +void ip_cleanup(Slirp *); void ip_input(struct mbuf *); void ip_slowtimo(Slirp *); void ip_stripoptions(register struct mbuf *, struct mbuf *); @@ -332,6 +333,7 @@ void tcp_setpersist(register struct tcpcb *); /* tcp_subr.c */ void tcp_init(Slirp *); +void tcp_cleanup(Slirp *); void tcp_template(struct tcpcb *); void tcp_respond(struct tcpcb *, register struct tcpiphdr *, register struct mbuf *, tcp_seq, tcp_seq, int); struct tcpcb * tcp_newtcpcb(struct socket *); diff --git a/slirp/tcp_subr.c b/slirp/tcp_subr.c index 143a2383c8..6f6585a10f 100644 --- a/slirp/tcp_subr.c +++ b/slirp/tcp_subr.c @@ -55,6 +55,13 @@ tcp_init(Slirp *slirp) slirp->tcp_last_so = &slirp->tcb; } +void tcp_cleanup(Slirp *slirp) +{ + while (slirp->tcb.so_next != &slirp->tcb) { + tcp_close(sototcpcb(slirp->tcb.so_next)); + } +} + /* * Create template to be used to send tcp packets on a connection. * Call after host entry created, fills diff --git a/slirp/udp.c b/slirp/udp.c index 5b060f397b..ced509656d 100644 --- a/slirp/udp.c +++ b/slirp/udp.c @@ -49,6 +49,14 @@ udp_init(Slirp *slirp) slirp->udb.so_next = slirp->udb.so_prev = &slirp->udb; slirp->udp_last_so = &slirp->udb; } + +void udp_cleanup(Slirp *slirp) +{ + while (slirp->udb.so_next != &slirp->udb) { + udp_detach(slirp->udb.so_next); + } +} + /* m->m_data points at ip packet header * m->m_len length ip packet * ip->ip_len length data (IPDU) diff --git a/slirp/udp.h b/slirp/udp.h index 9b5c3cf56a..9bf31fe7be 100644 --- a/slirp/udp.h +++ b/slirp/udp.h @@ -74,6 +74,7 @@ struct udpiphdr { struct mbuf; void udp_init(Slirp *); +void udp_cleanup(Slirp *); void udp_input(register struct mbuf *, int); int udp_output(struct socket *, struct mbuf *, struct sockaddr_in *); int udp_attach(struct socket *); -- 2.11.4.GIT