Add support for vmchannel socket migration (Gleb Natapov)
Signed-off-by: Gleb Natapov <gleb@redhat.com> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6243 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
		
							parent
							
								
									49ec9b4054
								
							
						
					
					
						commit
						062e55272e
					
				
							
								
								
									
										227
									
								
								slirp/slirp.c
									
									
									
									
									
								
							
							
						
						
									
										227
									
								
								slirp/slirp.c
									
									
									
									
									
								
							@ -23,6 +23,7 @@
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
#include "qemu-common.h"
 | 
					#include "qemu-common.h"
 | 
				
			||||||
#include "slirp.h"
 | 
					#include "slirp.h"
 | 
				
			||||||
 | 
					#include "hw/hw.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* host address */
 | 
					/* host address */
 | 
				
			||||||
struct in_addr our_addr;
 | 
					struct in_addr our_addr;
 | 
				
			||||||
@ -166,6 +167,9 @@ static void slirp_cleanup(void)
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void slirp_state_save(QEMUFile *f, void *opaque);
 | 
				
			||||||
 | 
					static int slirp_state_load(QEMUFile *f, void *opaque, int version_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void slirp_init(int restrict, char *special_ip)
 | 
					void slirp_init(int restrict, char *special_ip)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    //    debug_init("/tmp/slirp.log", DEBUG_DEFAULT);
 | 
					    //    debug_init("/tmp/slirp.log", DEBUG_DEFAULT);
 | 
				
			||||||
@ -201,6 +205,7 @@ void slirp_init(int restrict, char *special_ip)
 | 
				
			|||||||
    inet_aton(slirp_special_ip, &special_addr);
 | 
					    inet_aton(slirp_special_ip, &special_addr);
 | 
				
			||||||
    alias_addr.s_addr = special_addr.s_addr | htonl(CTL_ALIAS);
 | 
					    alias_addr.s_addr = special_addr.s_addr | htonl(CTL_ALIAS);
 | 
				
			||||||
    getouraddr();
 | 
					    getouraddr();
 | 
				
			||||||
 | 
					    register_savevm("slirp", 0, 1, slirp_state_save, slirp_state_load, NULL);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define CONN_CANFSEND(so) (((so)->so_state & (SS_FCANTSENDMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED)
 | 
					#define CONN_CANFSEND(so) (((so)->so_state & (SS_FCANTSENDMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED)
 | 
				
			||||||
@ -809,3 +814,225 @@ void slirp_socket_recv(int addr_low_byte, int guest_port, const uint8_t *buf,
 | 
				
			|||||||
    if (ret > 0)
 | 
					    if (ret > 0)
 | 
				
			||||||
        tcp_output(sototcpcb(so));
 | 
					        tcp_output(sototcpcb(so));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void slirp_tcp_save(QEMUFile *f, struct tcpcb *tp)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    qemu_put_sbe16(f, tp->t_state);
 | 
				
			||||||
 | 
					    for (i = 0; i < TCPT_NTIMERS; i++)
 | 
				
			||||||
 | 
					        qemu_put_sbe16(f, tp->t_timer[i]);
 | 
				
			||||||
 | 
					    qemu_put_sbe16(f, tp->t_rxtshift);
 | 
				
			||||||
 | 
					    qemu_put_sbe16(f, tp->t_rxtcur);
 | 
				
			||||||
 | 
					    qemu_put_sbe16(f, tp->t_dupacks);
 | 
				
			||||||
 | 
					    qemu_put_be16(f, tp->t_maxseg);
 | 
				
			||||||
 | 
					    qemu_put_sbyte(f, tp->t_force);
 | 
				
			||||||
 | 
					    qemu_put_be16(f, tp->t_flags);
 | 
				
			||||||
 | 
					    qemu_put_be32(f, tp->snd_una);
 | 
				
			||||||
 | 
					    qemu_put_be32(f, tp->snd_nxt);
 | 
				
			||||||
 | 
					    qemu_put_be32(f, tp->snd_up);
 | 
				
			||||||
 | 
					    qemu_put_be32(f, tp->snd_wl1);
 | 
				
			||||||
 | 
					    qemu_put_be32(f, tp->snd_wl2);
 | 
				
			||||||
 | 
					    qemu_put_be32(f, tp->iss);
 | 
				
			||||||
 | 
					    qemu_put_be32(f, tp->snd_wnd);
 | 
				
			||||||
 | 
					    qemu_put_be32(f, tp->rcv_wnd);
 | 
				
			||||||
 | 
					    qemu_put_be32(f, tp->rcv_nxt);
 | 
				
			||||||
 | 
					    qemu_put_be32(f, tp->rcv_up);
 | 
				
			||||||
 | 
					    qemu_put_be32(f, tp->irs);
 | 
				
			||||||
 | 
					    qemu_put_be32(f, tp->rcv_adv);
 | 
				
			||||||
 | 
					    qemu_put_be32(f, tp->snd_max);
 | 
				
			||||||
 | 
					    qemu_put_be32(f, tp->snd_cwnd);
 | 
				
			||||||
 | 
					    qemu_put_be32(f, tp->snd_ssthresh);
 | 
				
			||||||
 | 
					    qemu_put_sbe16(f, tp->t_idle);
 | 
				
			||||||
 | 
					    qemu_put_sbe16(f, tp->t_rtt);
 | 
				
			||||||
 | 
					    qemu_put_be32(f, tp->t_rtseq);
 | 
				
			||||||
 | 
					    qemu_put_sbe16(f, tp->t_srtt);
 | 
				
			||||||
 | 
					    qemu_put_sbe16(f, tp->t_rttvar);
 | 
				
			||||||
 | 
					    qemu_put_be16(f, tp->t_rttmin);
 | 
				
			||||||
 | 
					    qemu_put_be32(f, tp->max_sndwnd);
 | 
				
			||||||
 | 
					    qemu_put_byte(f, tp->t_oobflags);
 | 
				
			||||||
 | 
					    qemu_put_byte(f, tp->t_iobc);
 | 
				
			||||||
 | 
					    qemu_put_sbe16(f, tp->t_softerror);
 | 
				
			||||||
 | 
					    qemu_put_byte(f, tp->snd_scale);
 | 
				
			||||||
 | 
					    qemu_put_byte(f, tp->rcv_scale);
 | 
				
			||||||
 | 
					    qemu_put_byte(f, tp->request_r_scale);
 | 
				
			||||||
 | 
					    qemu_put_byte(f, tp->requested_s_scale);
 | 
				
			||||||
 | 
					    qemu_put_be32(f, tp->ts_recent);
 | 
				
			||||||
 | 
					    qemu_put_be32(f, tp->ts_recent_age);
 | 
				
			||||||
 | 
					    qemu_put_be32(f, tp->last_ack_sent);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void slirp_sbuf_save(QEMUFile *f, struct sbuf *sbuf)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint32_t off;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    qemu_put_be32(f, sbuf->sb_cc);
 | 
				
			||||||
 | 
					    qemu_put_be32(f, sbuf->sb_datalen);
 | 
				
			||||||
 | 
					    off = (uint32_t)(sbuf->sb_wptr - sbuf->sb_data);
 | 
				
			||||||
 | 
					    qemu_put_sbe32(f, off);
 | 
				
			||||||
 | 
					    off = (uint32_t)(sbuf->sb_rptr - sbuf->sb_data);
 | 
				
			||||||
 | 
					    qemu_put_sbe32(f, off);
 | 
				
			||||||
 | 
					    qemu_put_buffer(f, (unsigned char*)sbuf->sb_data, sbuf->sb_datalen);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void slirp_socket_save(QEMUFile *f, struct socket *so)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    qemu_put_be32(f, so->so_urgc);
 | 
				
			||||||
 | 
					    qemu_put_be32(f, so->so_faddr.s_addr);
 | 
				
			||||||
 | 
					    qemu_put_be32(f, so->so_laddr.s_addr);
 | 
				
			||||||
 | 
					    qemu_put_be16(f, so->so_fport);
 | 
				
			||||||
 | 
					    qemu_put_be16(f, so->so_lport);
 | 
				
			||||||
 | 
					    qemu_put_byte(f, so->so_iptos);
 | 
				
			||||||
 | 
					    qemu_put_byte(f, so->so_emu);
 | 
				
			||||||
 | 
					    qemu_put_byte(f, so->so_type);
 | 
				
			||||||
 | 
					    qemu_put_be32(f, so->so_state);
 | 
				
			||||||
 | 
					    slirp_sbuf_save(f, &so->so_rcv);
 | 
				
			||||||
 | 
					    slirp_sbuf_save(f, &so->so_snd);
 | 
				
			||||||
 | 
					    slirp_tcp_save(f, so->so_tcpcb);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void slirp_state_save(QEMUFile *f, void *opaque)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    struct ex_list *ex_ptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next)
 | 
				
			||||||
 | 
					        if (ex_ptr->ex_pty == 3) {
 | 
				
			||||||
 | 
					            struct socket *so;
 | 
				
			||||||
 | 
					            so = slirp_find_ctl_socket(ex_ptr->ex_addr, ntohs(ex_ptr->ex_fport));
 | 
				
			||||||
 | 
					            if (!so)
 | 
				
			||||||
 | 
					                continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            qemu_put_byte(f, 42);
 | 
				
			||||||
 | 
					            slirp_socket_save(f, so);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    qemu_put_byte(f, 0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void slirp_tcp_load(QEMUFile *f, struct tcpcb *tp)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    tp->t_state = qemu_get_sbe16(f);
 | 
				
			||||||
 | 
					    for (i = 0; i < TCPT_NTIMERS; i++)
 | 
				
			||||||
 | 
					        tp->t_timer[i] = qemu_get_sbe16(f);
 | 
				
			||||||
 | 
					    tp->t_rxtshift = qemu_get_sbe16(f);
 | 
				
			||||||
 | 
					    tp->t_rxtcur = qemu_get_sbe16(f);
 | 
				
			||||||
 | 
					    tp->t_dupacks = qemu_get_sbe16(f);
 | 
				
			||||||
 | 
					    tp->t_maxseg = qemu_get_be16(f);
 | 
				
			||||||
 | 
					    tp->t_force = qemu_get_sbyte(f);
 | 
				
			||||||
 | 
					    tp->t_flags = qemu_get_be16(f);
 | 
				
			||||||
 | 
					    tp->snd_una = qemu_get_be32(f);
 | 
				
			||||||
 | 
					    tp->snd_nxt = qemu_get_be32(f);
 | 
				
			||||||
 | 
					    tp->snd_up = qemu_get_be32(f);
 | 
				
			||||||
 | 
					    tp->snd_wl1 = qemu_get_be32(f);
 | 
				
			||||||
 | 
					    tp->snd_wl2 = qemu_get_be32(f);
 | 
				
			||||||
 | 
					    tp->iss = qemu_get_be32(f);
 | 
				
			||||||
 | 
					    tp->snd_wnd = qemu_get_be32(f);
 | 
				
			||||||
 | 
					    tp->rcv_wnd = qemu_get_be32(f);
 | 
				
			||||||
 | 
					    tp->rcv_nxt = qemu_get_be32(f);
 | 
				
			||||||
 | 
					    tp->rcv_up = qemu_get_be32(f);
 | 
				
			||||||
 | 
					    tp->irs = qemu_get_be32(f);
 | 
				
			||||||
 | 
					    tp->rcv_adv = qemu_get_be32(f);
 | 
				
			||||||
 | 
					    tp->snd_max = qemu_get_be32(f);
 | 
				
			||||||
 | 
					    tp->snd_cwnd = qemu_get_be32(f);
 | 
				
			||||||
 | 
					    tp->snd_ssthresh = qemu_get_be32(f);
 | 
				
			||||||
 | 
					    tp->t_idle = qemu_get_sbe16(f);
 | 
				
			||||||
 | 
					    tp->t_rtt = qemu_get_sbe16(f);
 | 
				
			||||||
 | 
					    tp->t_rtseq = qemu_get_be32(f);
 | 
				
			||||||
 | 
					    tp->t_srtt = qemu_get_sbe16(f);
 | 
				
			||||||
 | 
					    tp->t_rttvar = qemu_get_sbe16(f);
 | 
				
			||||||
 | 
					    tp->t_rttmin = qemu_get_be16(f);
 | 
				
			||||||
 | 
					    tp->max_sndwnd = qemu_get_be32(f);
 | 
				
			||||||
 | 
					    tp->t_oobflags = qemu_get_byte(f);
 | 
				
			||||||
 | 
					    tp->t_iobc = qemu_get_byte(f);
 | 
				
			||||||
 | 
					    tp->t_softerror = qemu_get_sbe16(f);
 | 
				
			||||||
 | 
					    tp->snd_scale = qemu_get_byte(f);
 | 
				
			||||||
 | 
					    tp->rcv_scale = qemu_get_byte(f);
 | 
				
			||||||
 | 
					    tp->request_r_scale = qemu_get_byte(f);
 | 
				
			||||||
 | 
					    tp->requested_s_scale = qemu_get_byte(f);
 | 
				
			||||||
 | 
					    tp->ts_recent = qemu_get_be32(f);
 | 
				
			||||||
 | 
					    tp->ts_recent_age = qemu_get_be32(f);
 | 
				
			||||||
 | 
					    tp->last_ack_sent = qemu_get_be32(f);
 | 
				
			||||||
 | 
					    tcp_template(tp);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int slirp_sbuf_load(QEMUFile *f, struct sbuf *sbuf)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint32_t off, sb_cc, sb_datalen;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    sb_cc = qemu_get_be32(f);
 | 
				
			||||||
 | 
					    sb_datalen = qemu_get_be32(f);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    sbreserve(sbuf, sb_datalen);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (sbuf->sb_datalen != sb_datalen)
 | 
				
			||||||
 | 
					        return -ENOMEM;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    sbuf->sb_cc = sb_cc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    off = qemu_get_sbe32(f);
 | 
				
			||||||
 | 
					    sbuf->sb_wptr = sbuf->sb_data + off;
 | 
				
			||||||
 | 
					    off = qemu_get_sbe32(f);
 | 
				
			||||||
 | 
					    sbuf->sb_rptr = sbuf->sb_data + off;
 | 
				
			||||||
 | 
					    qemu_get_buffer(f, (unsigned char*)sbuf->sb_data, sbuf->sb_datalen);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int slirp_socket_load(QEMUFile *f, struct socket *so)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (tcp_attach(so) < 0)
 | 
				
			||||||
 | 
					        return -ENOMEM;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    so->so_urgc = qemu_get_be32(f);
 | 
				
			||||||
 | 
					    so->so_faddr.s_addr = qemu_get_be32(f);
 | 
				
			||||||
 | 
					    so->so_laddr.s_addr = qemu_get_be32(f);
 | 
				
			||||||
 | 
					    so->so_fport = qemu_get_be16(f);
 | 
				
			||||||
 | 
					    so->so_lport = qemu_get_be16(f);
 | 
				
			||||||
 | 
					    so->so_iptos = qemu_get_byte(f);
 | 
				
			||||||
 | 
					    so->so_emu = qemu_get_byte(f);
 | 
				
			||||||
 | 
					    so->so_type = qemu_get_byte(f);
 | 
				
			||||||
 | 
					    so->so_state = qemu_get_be32(f);
 | 
				
			||||||
 | 
					    if (slirp_sbuf_load(f, &so->so_rcv) < 0)
 | 
				
			||||||
 | 
					        return -ENOMEM;
 | 
				
			||||||
 | 
					    if (slirp_sbuf_load(f, &so->so_snd) < 0)
 | 
				
			||||||
 | 
					        return -ENOMEM;
 | 
				
			||||||
 | 
					    slirp_tcp_load(f, so->so_tcpcb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int slirp_state_load(QEMUFile *f, void *opaque, int version_id)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    struct ex_list *ex_ptr;
 | 
				
			||||||
 | 
					    int r;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    while ((r = qemu_get_byte(f))) {
 | 
				
			||||||
 | 
					        int ret;
 | 
				
			||||||
 | 
					        struct socket *so = socreate();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!so)
 | 
				
			||||||
 | 
					            return -ENOMEM;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        ret = slirp_socket_load(f, so);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (ret < 0)
 | 
				
			||||||
 | 
					            return ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ((so->so_faddr.s_addr & htonl(0xffffff00)) != special_addr.s_addr)
 | 
				
			||||||
 | 
					            return -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for (ex_ptr = exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next)
 | 
				
			||||||
 | 
					            if (ex_ptr->ex_pty == 3 &&
 | 
				
			||||||
 | 
					                    (ntohl(so->so_faddr.s_addr) & 0xff) == ex_ptr->ex_addr &&
 | 
				
			||||||
 | 
					                    so->so_fport == ex_ptr->ex_fport)
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!ex_ptr)
 | 
				
			||||||
 | 
					            return -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        so->extra = ex_ptr->ex_exec;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user