qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 00/10] [RESEND] Various net and slirp fixes & enhancements
@ 2011-07-20 10:20 Jan Kiszka
  2011-07-20 10:20 ` [Qemu-devel] [PATCH 01/10] slirp: Fix restricted mode Jan Kiszka
                   ` (11 more replies)
  0 siblings, 12 replies; 13+ messages in thread
From: Jan Kiszka @ 2011-07-20 10:20 UTC (permalink / raw)
  To: Anthony Liguori, qemu-devel
  Cc: Peter Maydell, Markus Armbruster, Gleb Natapov

Almost just a reposting of the previously sent series. No patch
modified, but a nifty (IMO) new one: ping forwarding for slirp using
the unprivileged ICMP sockets of Linux 3.0. See commit log for a simple
how-to.

CC: Gleb Natapov <gleb@redhat.com>
CC: Markus Armbruster <armbru@redhat.com>
CC: Peter Maydell <peter.maydell@linaro.org>

Jan Kiszka (10):
  slirp: Fix restricted mode
  slirp: Canonicalize restrict syntax
  slirp: Strictly associate DHCP/BOOTP and TFTP with virtual host
  slirp: Replace m_freem with m_free
  slirp: Put forked exec into separate process group
  slirp: Forward ICMP echo requests via unprivileged sockets
  net: Improve layout of 'info network'
  net: Refactor net_client_types
  net: Dump client type 'info network'
  net: Consistently use qemu_macaddr_default_if_unset

 hw/dp8393x.c       |    2 +-
 hw/etraxfs_eth.c   |    2 +-
 hw/mcf_fec.c       |    2 +-
 hw/mipsnet.c       |    2 +-
 hw/qdev.c          |    2 +-
 hw/stellaris.c     |    2 +-
 hw/xen_devconfig.c |    4 +-
 net.c              |   65 +++++++++++++++++++++--------------
 net.h              |    8 +++--
 net/slirp.c        |   23 +++++++++----
 qemu-options.hx    |    4 +-
 slirp/ip_icmp.c    |   95 +++++++++++++++++++++++++++++++++++++++++++++++++--
 slirp/ip_icmp.h    |    3 ++
 slirp/ip_input.c   |   30 +++--------------
 slirp/ip_output.c  |    4 +-
 slirp/mbuf.h       |    3 --
 slirp/misc.c       |   16 ++++++++-
 slirp/slirp.c      |   37 ++++++++++++++++++++
 slirp/slirp.h      |    5 +++
 slirp/socket.c     |    2 +
 slirp/tcp_input.c  |   10 +++---
 slirp/tcp_subr.c   |    2 +-
 slirp/udp.c        |   23 +++++++-----
 23 files changed, 249 insertions(+), 97 deletions(-)

-- 
1.7.3.4

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [Qemu-devel] [PATCH 01/10] slirp: Fix restricted mode
  2011-07-20 10:20 [Qemu-devel] [PATCH 00/10] [RESEND] Various net and slirp fixes & enhancements Jan Kiszka
@ 2011-07-20 10:20 ` Jan Kiszka
  2011-07-20 10:20 ` [Qemu-devel] [PATCH 02/10] slirp: Canonicalize restrict syntax Jan Kiszka
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Jan Kiszka @ 2011-07-20 10:20 UTC (permalink / raw)
  To: Anthony Liguori, qemu-devel; +Cc: Gleb Natapov

This aligns the code to what the documentation claims: Allow everything
but requests that would have to be routed outside of the virtual LAN.

So we need to drop the unneeded IP-level filter, allow TFTP requests,
and add the missing protocol-level filter to ICMP.

CC: Gleb Natapov <gleb@redhat.com>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 slirp/ip_icmp.c  |    2 ++
 slirp/ip_input.c |   21 ---------------------
 slirp/udp.c      |    8 ++++----
 3 files changed, 6 insertions(+), 25 deletions(-)

diff --git a/slirp/ip_icmp.c b/slirp/ip_icmp.c
index 751a8e2..0cd129c 100644
--- a/slirp/ip_icmp.c
+++ b/slirp/ip_icmp.c
@@ -101,6 +101,8 @@ icmp_input(struct mbuf *m, int hlen)
     ip->ip_len += hlen;	             /* since ip_input subtracts this */
     if (ip->ip_dst.s_addr == slirp->vhost_addr.s_addr) {
       icmp_reflect(m);
+    } else if (slirp->restricted) {
+        goto freeit;
     } else {
       struct socket *so;
       struct sockaddr_in addr;
diff --git a/slirp/ip_input.c b/slirp/ip_input.c
index 768ab0c..2ff6adb 100644
--- a/slirp/ip_input.c
+++ b/slirp/ip_input.c
@@ -118,27 +118,6 @@ ip_input(struct mbuf *m)
 		goto bad;
 	}
 
-    if (slirp->restricted) {
-        if ((ip->ip_dst.s_addr & slirp->vnetwork_mask.s_addr) ==
-            slirp->vnetwork_addr.s_addr) {
-            if (ip->ip_dst.s_addr == 0xffffffff && ip->ip_p != IPPROTO_UDP)
-                goto bad;
-        } else {
-            uint32_t inv_mask = ~slirp->vnetwork_mask.s_addr;
-            struct ex_list *ex_ptr;
-
-            if ((ip->ip_dst.s_addr & inv_mask) == inv_mask) {
-                goto bad;
-            }
-            for (ex_ptr = slirp->exec_list; ex_ptr; ex_ptr = ex_ptr->ex_next)
-                if (ex_ptr->ex_addr.s_addr == ip->ip_dst.s_addr)
-                    break;
-
-            if (!ex_ptr)
-                goto bad;
-        }
-    }
-
 	/* Should drop packet if mbuf too long? hmmm... */
 	if (m->m_len > ip->ip_len)
 	   m_adj(m, ip->ip_len - m->m_len);
diff --git a/slirp/udp.c b/slirp/udp.c
index 02b3793..f1a9a10 100644
--- a/slirp/udp.c
+++ b/slirp/udp.c
@@ -125,10 +125,6 @@ udp_input(register struct mbuf *m, int iphlen)
             goto bad;
         }
 
-        if (slirp->restricted) {
-            goto bad;
-        }
-
         /*
          *  handle TFTP
          */
@@ -137,6 +133,10 @@ udp_input(register struct mbuf *m, int iphlen)
             goto bad;
         }
 
+        if (slirp->restricted) {
+            goto bad;
+        }
+
 	/*
 	 * Locate pcb for datagram.
 	 */
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [Qemu-devel] [PATCH 02/10] slirp: Canonicalize restrict syntax
  2011-07-20 10:20 [Qemu-devel] [PATCH 00/10] [RESEND] Various net and slirp fixes & enhancements Jan Kiszka
  2011-07-20 10:20 ` [Qemu-devel] [PATCH 01/10] slirp: Fix restricted mode Jan Kiszka
@ 2011-07-20 10:20 ` Jan Kiszka
  2011-07-20 10:20 ` [Qemu-devel] [PATCH 03/10] slirp: Strictly associate DHCP/BOOTP and TFTP with virtual host Jan Kiszka
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Jan Kiszka @ 2011-07-20 10:20 UTC (permalink / raw)
  To: Anthony Liguori, qemu-devel; +Cc: Gleb Natapov

All other boolean arguments accept on|off - except for slirp's restrict.
Fix that while still accepting the formerly allowed yes|y|no|n, but
reject everything else. This avoids accidentally allowing external
connections because syntax errors were so far interpreted as
'restrict=no'.

CC: Gleb Natapov <gleb@redhat.com>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 net/slirp.c     |   21 +++++++++++++++------
 qemu-options.hx |    4 ++--
 2 files changed, 17 insertions(+), 8 deletions(-)

diff --git a/net/slirp.c b/net/slirp.c
index e057a14..71e2577 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -240,7 +240,8 @@ static int net_slirp_init(VLANState *vlan, const char *model,
     nc = qemu_new_net_client(&net_slirp_info, vlan, NULL, model, name);
 
     snprintf(nc->info_str, sizeof(nc->info_str),
-             "net=%s, restricted=%c", inet_ntoa(net), restricted ? 'y' : 'n');
+             "net=%s,restrict=%s", inet_ntoa(net),
+             restricted ? "on" : "off");
 
     s = DO_UPCAST(SlirpState, nc, nc);
 
@@ -689,6 +690,7 @@ int net_init_slirp(QemuOpts *opts,
     const char *bootfile;
     const char *smb_export;
     const char *vsmbsrv;
+    const char *restrict_opt;
     char *vnet = NULL;
     int restricted = 0;
     int ret;
@@ -702,6 +704,18 @@ int net_init_slirp(QemuOpts *opts,
     smb_export  = qemu_opt_get(opts, "smb");
     vsmbsrv     = qemu_opt_get(opts, "smbserver");
 
+    restrict_opt = qemu_opt_get(opts, "restrict");
+    if (restrict_opt) {
+        if (!strcmp(restrict_opt, "on") ||
+            !strcmp(restrict_opt, "yes") || !strcmp(restrict_opt, "y")) {
+            restricted = 1;
+        } else if (strcmp(restrict_opt, "off") &&
+            strcmp(restrict_opt, "no") && strcmp(restrict_opt, "n")) {
+            error_report("invalid option: 'restrict=%s'", restrict_opt);
+            return -1;
+        }
+    }
+
     if (qemu_opt_get(opts, "ip")) {
         const char *ip = qemu_opt_get(opts, "ip");
         int l = strlen(ip) + strlen("/24") + 1;
@@ -720,11 +734,6 @@ int net_init_slirp(QemuOpts *opts,
         vnet = qemu_strdup(qemu_opt_get(opts, "net"));
     }
 
-    if (qemu_opt_get(opts, "restrict") &&
-        qemu_opt_get(opts, "restrict")[0] == 'y') {
-        restricted = 1;
-    }
-
     qemu_opt_foreach(opts, net_init_slirp_configs, NULL, 0);
 
     ret = net_slirp_init(vlan, "user", name, restricted, vnet, vhost,
diff --git a/qemu-options.hx b/qemu-options.hx
index e6d7adc..0f58e27 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -1092,7 +1092,7 @@ DEF("net", HAS_ARG, QEMU_OPTION_net,
     "-net nic[,vlan=n][,macaddr=mac][,model=type][,name=str][,addr=str][,vectors=v]\n"
     "                create a new Network Interface Card and connect it to VLAN 'n'\n"
 #ifdef CONFIG_SLIRP
-    "-net user[,vlan=n][,name=str][,net=addr[/mask]][,host=addr][,restrict=y|n]\n"
+    "-net user[,vlan=n][,name=str][,net=addr[/mask]][,host=addr][,restrict=on|off]\n"
     "         [,hostname=host][,dhcpstart=addr][,dns=addr][,tftp=dir][,bootfile=f]\n"
     "         [,hostfwd=rule][,guestfwd=rule]"
 #ifndef _WIN32
@@ -1185,7 +1185,7 @@ either in the form a.b.c.d or as number of valid top-most bits. Default is
 Specify the guest-visible address of the host. Default is the 2nd IP in the
 guest network, i.e. x.x.x.2.
 
-@item restrict=y|yes|n|no
+@item restrict=on|off
 If this option is enabled, the guest will be isolated, i.e. it will not be
 able to contact the host and no guest IP packets will be routed over the host
 to the outside. This option does not affect any explicitly set forwarding rules.
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [Qemu-devel] [PATCH 03/10] slirp: Strictly associate DHCP/BOOTP and TFTP with virtual host
  2011-07-20 10:20 [Qemu-devel] [PATCH 00/10] [RESEND] Various net and slirp fixes & enhancements Jan Kiszka
  2011-07-20 10:20 ` [Qemu-devel] [PATCH 01/10] slirp: Fix restricted mode Jan Kiszka
  2011-07-20 10:20 ` [Qemu-devel] [PATCH 02/10] slirp: Canonicalize restrict syntax Jan Kiszka
@ 2011-07-20 10:20 ` Jan Kiszka
  2011-07-20 10:20 ` [Qemu-devel] [PATCH 04/10] slirp: Replace m_freem with m_free Jan Kiszka
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Jan Kiszka @ 2011-07-20 10:20 UTC (permalink / raw)
  To: Anthony Liguori, qemu-devel

Instead of accepting every DHCP/BOOTP and TFTP packet, only invoke the
built-in servers if the target is the virtual host.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 slirp/udp.c |   13 ++++++++-----
 1 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/slirp/udp.c b/slirp/udp.c
index f1a9a10..cefd50b 100644
--- a/slirp/udp.c
+++ b/slirp/udp.c
@@ -120,15 +120,18 @@ udp_input(register struct mbuf *m, int iphlen)
         /*
          *  handle DHCP/BOOTP
          */
-        if (ntohs(uh->uh_dport) == BOOTP_SERVER) {
-            bootp_input(m);
-            goto bad;
-        }
+        if (ntohs(uh->uh_dport) == BOOTP_SERVER &&
+            (ip->ip_dst.s_addr == slirp->vhost_addr.s_addr ||
+             ip->ip_dst.s_addr == 0xffffffff)) {
+                bootp_input(m);
+                goto bad;
+            }
 
         /*
          *  handle TFTP
          */
-        if (ntohs(uh->uh_dport) == TFTP_SERVER) {
+        if (ntohs(uh->uh_dport) == TFTP_SERVER &&
+            ip->ip_dst.s_addr == slirp->vhost_addr.s_addr) {
             tftp_input(m);
             goto bad;
         }
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [Qemu-devel] [PATCH 04/10] slirp: Replace m_freem with m_free
  2011-07-20 10:20 [Qemu-devel] [PATCH 00/10] [RESEND] Various net and slirp fixes & enhancements Jan Kiszka
                   ` (2 preceding siblings ...)
  2011-07-20 10:20 ` [Qemu-devel] [PATCH 03/10] slirp: Strictly associate DHCP/BOOTP and TFTP with virtual host Jan Kiszka
@ 2011-07-20 10:20 ` Jan Kiszka
  2011-07-20 10:20 ` [Qemu-devel] [PATCH 05/10] slirp: Put forked exec into separate process group Jan Kiszka
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Jan Kiszka @ 2011-07-20 10:20 UTC (permalink / raw)
  To: Anthony Liguori, qemu-devel

Remove this pointless wrapping.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 slirp/ip_icmp.c   |    6 +++---
 slirp/ip_input.c  |    8 ++++----
 slirp/ip_output.c |    4 ++--
 slirp/mbuf.h      |    3 ---
 slirp/tcp_input.c |   10 +++++-----
 slirp/tcp_subr.c  |    2 +-
 slirp/udp.c       |    2 +-
 7 files changed, 16 insertions(+), 19 deletions(-)

diff --git a/slirp/ip_icmp.c b/slirp/ip_icmp.c
index 0cd129c..4f10826 100644
--- a/slirp/ip_icmp.c
+++ b/slirp/ip_icmp.c
@@ -81,7 +81,7 @@ icmp_input(struct mbuf *m, int hlen)
    */
   if (icmplen < ICMP_MINLEN) {          /* min 8 bytes payload */
   freeit:
-    m_freem(m);
+    m_free(m);
     goto end_error;
   }
 
@@ -155,11 +155,11 @@ icmp_input(struct mbuf *m, int hlen)
   case ICMP_TSTAMP:
   case ICMP_MASKREQ:
   case ICMP_REDIRECT:
-    m_freem(m);
+    m_free(m);
     break;
 
   default:
-    m_freem(m);
+    m_free(m);
   } /* swith */
 
 end_error:
diff --git a/slirp/ip_input.c b/slirp/ip_input.c
index 2ff6adb..46c60b0 100644
--- a/slirp/ip_input.c
+++ b/slirp/ip_input.c
@@ -204,7 +204,7 @@ ip_input(struct mbuf *m)
 	}
 	return;
 bad:
-	m_freem(m);
+	m_free(m);
 	return;
 }
 
@@ -297,7 +297,7 @@ ip_reass(Slirp *slirp, struct ip *ip, struct ipq *fp)
 			break;
 		}
 		q = q->ipf_next;
-		m_freem(dtom(slirp, q->ipf_prev));
+		m_free(dtom(slirp, q->ipf_prev));
 		ip_deq(q->ipf_prev);
 	}
 
@@ -363,7 +363,7 @@ insert:
 	return ip;
 
 dropfrag:
-	m_freem(m);
+	m_free(m);
         return NULL;
 }
 
@@ -379,7 +379,7 @@ ip_freef(Slirp *slirp, struct ipq *fp)
 	for (q = fp->frag_link.next; q != (struct ipasfrag*)&fp->frag_link; q = p) {
 		p = q->ipf_next;
 		ip_deq(q);
-		m_freem(dtom(slirp, q));
+		m_free(dtom(slirp, q));
 	}
 	remque(&fp->ip_link);
 	(void) m_free(dtom(slirp, fp));
diff --git a/slirp/ip_output.c b/slirp/ip_output.c
index 542f318..c82830f 100644
--- a/slirp/ip_output.c
+++ b/slirp/ip_output.c
@@ -159,7 +159,7 @@ sendorfree:
 		if (error == 0)
 			if_output(so, m);
 		else
-			m_freem(m);
+			m_free(m);
 	}
     }
 
@@ -167,6 +167,6 @@ done:
 	return (error);
 
 bad:
-	m_freem(m0);
+	m_free(m0);
 	goto done;
 }
diff --git a/slirp/mbuf.h b/slirp/mbuf.h
index 97729e2..b74544b 100644
--- a/slirp/mbuf.h
+++ b/slirp/mbuf.h
@@ -33,9 +33,6 @@
 #ifndef _MBUF_H_
 #define _MBUF_H_
 
-#define m_freem m_free
-
-
 #define MINCSIZE 4096	/* Amount to increase mbuf if too small */
 
 /*
diff --git a/slirp/tcp_input.c b/slirp/tcp_input.c
index e4a7731..c1214c0 100644
--- a/slirp/tcp_input.c
+++ b/slirp/tcp_input.c
@@ -136,7 +136,7 @@ tcp_reass(register struct tcpcb *tp, register struct tcpiphdr *ti,
 		i = q->ti_seq + q->ti_len - ti->ti_seq;
 		if (i > 0) {
 			if (i >= ti->ti_len) {
-				m_freem(m);
+				m_free(m);
 				/*
 				 * Try to present any queued data
 				 * at the left window edge to the user.
@@ -170,7 +170,7 @@ tcp_reass(register struct tcpcb *tp, register struct tcpiphdr *ti,
 		q = tcpiphdr_next(q);
 		m = tcpiphdr_prev(q)->ti_mbuf;
 		remque(tcpiphdr2qlink(tcpiphdr_prev(q)));
-		m_freem(m);
+		m_free(m);
 	}
 
 	/*
@@ -197,7 +197,7 @@ present:
 		m = ti->ti_mbuf;
 		ti = tcpiphdr_next(ti);
 		if (so->so_state & SS_FCANTSENDMORE)
-			m_freem(m);
+			m_free(m);
 		else {
 			if (so->so_emu) {
 				if (tcp_emu(so,m)) sbappend(so, m);
@@ -451,7 +451,7 @@ findso:
 				acked = ti->ti_ack - tp->snd_una;
 				sbdrop(&so->so_snd, acked);
 				tp->snd_una = ti->ti_ack;
-				m_freem(m);
+				m_free(m);
 
 				/*
 				 * If all outstanding data are acked, stop
@@ -1260,7 +1260,7 @@ dropafterack:
 	 */
 	if (tiflags & TH_RST)
 		goto drop;
-	m_freem(m);
+	m_free(m);
 	tp->t_flags |= TF_ACKNOW;
 	(void) tcp_output(tp);
 	return;
diff --git a/slirp/tcp_subr.c b/slirp/tcp_subr.c
index b661d26..61079b1 100644
--- a/slirp/tcp_subr.c
+++ b/slirp/tcp_subr.c
@@ -250,7 +250,7 @@ tcp_close(struct tcpcb *tp)
 		t = tcpiphdr_next(t);
 		m = tcpiphdr_prev(t)->ti_mbuf;
 		remque(tcpiphdr2qlink(tcpiphdr_prev(t)));
-		m_freem(m);
+		m_free(m);
 	}
 	free(tp);
         so->so_tcpcb = NULL;
diff --git a/slirp/udp.c b/slirp/udp.c
index cefd50b..5b060f3 100644
--- a/slirp/udp.c
+++ b/slirp/udp.c
@@ -222,7 +222,7 @@ udp_input(register struct mbuf *m, int iphlen)
 
 	return;
 bad:
-	m_freem(m);
+	m_free(m);
 	return;
 }
 
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [Qemu-devel] [PATCH 05/10] slirp: Put forked exec into separate process group
  2011-07-20 10:20 [Qemu-devel] [PATCH 00/10] [RESEND] Various net and slirp fixes & enhancements Jan Kiszka
                   ` (3 preceding siblings ...)
  2011-07-20 10:20 ` [Qemu-devel] [PATCH 04/10] slirp: Replace m_freem with m_free Jan Kiszka
@ 2011-07-20 10:20 ` Jan Kiszka
  2011-07-20 10:20 ` [Qemu-devel] [PATCH 06/10] slirp: Forward ICMP echo requests via unprivileged sockets Jan Kiszka
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Jan Kiszka @ 2011-07-20 10:20 UTC (permalink / raw)
  To: Anthony Liguori, qemu-devel

Recent smb daemons tend to terminate themselves via a process group
SIGTERM. If the daemon is still in qemu's group by that time, qemu will
die as well. Avoid this by always pushing fork_exec processes into a
group of their own, not just (unused) type 2 execs.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 slirp/misc.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/slirp/misc.c b/slirp/misc.c
index 08eba6a..34179e2 100644
--- a/slirp/misc.c
+++ b/slirp/misc.c
@@ -153,11 +153,12 @@ fork_exec(struct socket *so, const char *ex, int do_pty)
 		return 0;
 
 	 case 0:
+                setsid();
+
 		/* Set the DISPLAY */
 		if (do_pty == 2) {
 			(void) close(master);
 #ifdef TIOCSCTTY /* XXXXX */
-			(void) setsid();
 			ioctl(s, TIOCSCTTY, (char *)NULL);
 #endif
 		} else {
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [Qemu-devel] [PATCH 06/10] slirp: Forward ICMP echo requests via unprivileged sockets
  2011-07-20 10:20 [Qemu-devel] [PATCH 00/10] [RESEND] Various net and slirp fixes & enhancements Jan Kiszka
                   ` (4 preceding siblings ...)
  2011-07-20 10:20 ` [Qemu-devel] [PATCH 05/10] slirp: Put forked exec into separate process group Jan Kiszka
@ 2011-07-20 10:20 ` Jan Kiszka
  2011-07-20 10:20 ` [Qemu-devel] [PATCH 07/10] net: Improve layout of 'info network' Jan Kiszka
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Jan Kiszka @ 2011-07-20 10:20 UTC (permalink / raw)
  To: Anthony Liguori, qemu-devel

Linux 3.0 gained support for unprivileged ICMP ping sockets. Use this
feature to forward guest pings to the outer world. The host admin has to
set the ping_group_range in order to grant access to those sockets. To
allow ping for the users group (GID 100):

echo 100 100 > /proc/sys/net/ipv4/ping_group_range

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 slirp/ip_icmp.c  |   87 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
 slirp/ip_icmp.h  |    3 ++
 slirp/ip_input.c |    1 +
 slirp/misc.c     |   13 ++++++++
 slirp/slirp.c    |   37 +++++++++++++++++++++++
 slirp/slirp.h    |    5 +++
 slirp/socket.c   |    2 +
 7 files changed, 147 insertions(+), 1 deletions(-)

diff --git a/slirp/ip_icmp.c b/slirp/ip_icmp.c
index 4f10826..14a5312 100644
--- a/slirp/ip_icmp.c
+++ b/slirp/ip_icmp.c
@@ -60,6 +60,52 @@ static const int icmp_flush[19] = {
 /* ADDR MASK REPLY (18) */ 0
 };
 
+void icmp_init(Slirp *slirp)
+{
+    slirp->icmp.so_next = slirp->icmp.so_prev = &slirp->icmp;
+    slirp->icmp_last_so = &slirp->icmp;
+}
+
+static int icmp_send(struct socket *so, struct mbuf *m, int hlen)
+{
+    struct ip *ip = mtod(m, struct ip *);
+    struct sockaddr_in addr;
+
+    so->s = qemu_socket(AF_INET, SOCK_DGRAM, IPPROTO_ICMP);
+    if (so->s == -1) {
+        return -1;
+    }
+
+    so->so_m = m;
+    so->so_faddr = ip->ip_dst;
+    so->so_laddr = ip->ip_src;
+    so->so_iptos = ip->ip_tos;
+    so->so_type = IPPROTO_ICMP;
+    so->so_state = SS_ISFCONNECTED;
+    so->so_expire = curtime + SO_EXPIRE;
+
+    addr.sin_family = AF_INET;
+    addr.sin_addr = so->so_faddr;
+
+    insque(so, &so->slirp->icmp);
+
+    if (sendto(so->s, m->m_data + hlen, m->m_len - hlen, 0,
+               (struct sockaddr *)&addr, sizeof(addr)) == -1) {
+        DEBUG_MISC((dfd, "icmp_input icmp sendto tx errno = %d-%s\n",
+                    errno, strerror(errno)));
+        icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_NET, 0, strerror(errno));
+        icmp_detach(so);
+    }
+
+    return 0;
+}
+
+void icmp_detach(struct socket *so)
+{
+    closesocket(so->s);
+    sofree(so);
+}
+
 /*
  * Process a received ICMP message.
  */
@@ -97,7 +143,6 @@ icmp_input(struct mbuf *m, int hlen)
   DEBUG_ARG("icmp_type = %d", icp->icmp_type);
   switch (icp->icmp_type) {
   case ICMP_ECHO:
-    icp->icmp_type = ICMP_ECHOREPLY;
     ip->ip_len += hlen;	             /* since ip_input subtracts this */
     if (ip->ip_dst.s_addr == slirp->vhost_addr.s_addr) {
       icmp_reflect(m);
@@ -107,6 +152,9 @@ icmp_input(struct mbuf *m, int hlen)
       struct socket *so;
       struct sockaddr_in addr;
       if ((so = socreate(slirp)) == NULL) goto freeit;
+      if (icmp_send(so, m, hlen) == 0) {
+        return;
+      }
       if(udp_attach(so) == -1) {
 	DEBUG_MISC((dfd,"icmp_input udp_attach errno = %d-%s\n",
 		    errno,strerror(errno)));
@@ -321,6 +369,7 @@ icmp_reflect(struct mbuf *m)
   m->m_len -= hlen;
   icp = mtod(m, struct icmp *);
 
+  icp->icmp_type = ICMP_ECHOREPLY;
   icp->icmp_cksum = 0;
   icp->icmp_cksum = cksum(m, ip->ip_len - hlen);
 
@@ -351,3 +400,39 @@ icmp_reflect(struct mbuf *m)
 
   (void ) ip_output((struct socket *)NULL, m);
 }
+
+void icmp_receive(struct socket *so)
+{
+    struct mbuf *m = so->so_m;
+    struct ip *ip = mtod(m, struct ip *);
+    int hlen = ip->ip_hl << 2;
+    u_char error_code;
+    struct icmp *icp;
+    int id, len;
+
+    m->m_data += hlen;
+    m->m_len -= hlen;
+    icp = mtod(m, struct icmp *);
+
+    id = icp->icmp_id;
+    len = recv(so->s, icp, m->m_len, 0);
+    icp->icmp_id = id;
+
+    m->m_data -= hlen;
+    m->m_len += hlen;
+
+    if (len == -1 || len == 0) {
+        if (errno == ENETUNREACH) {
+            error_code = ICMP_UNREACH_NET;
+        } else {
+            error_code = ICMP_UNREACH_HOST;
+        }
+        DEBUG_MISC((dfd, " udp icmp rx errno = %d-%s\n", errno,
+                    strerror(errno)));
+        icmp_error(so->so_m, ICMP_UNREACH, error_code, 0, strerror(errno));
+    } else {
+        icmp_reflect(so->so_m);
+        so->so_m = NULL; /* Don't m_free() it again! */
+    }
+    icmp_detach(so);
+}
diff --git a/slirp/ip_icmp.h b/slirp/ip_icmp.h
index 2692822..b3da1f2 100644
--- a/slirp/ip_icmp.h
+++ b/slirp/ip_icmp.h
@@ -153,9 +153,12 @@ struct icmp {
 	(type) == ICMP_IREQ || (type) == ICMP_IREQREPLY || \
 	(type) == ICMP_MASKREQ || (type) == ICMP_MASKREPLY)
 
+void icmp_init(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);
 void icmp_reflect(struct mbuf *);
+void icmp_receive(struct socket *so);
+void icmp_detach(struct socket *so);
 
 #endif
diff --git a/slirp/ip_input.c b/slirp/ip_input.c
index 46c60b0..5e67631 100644
--- a/slirp/ip_input.c
+++ b/slirp/ip_input.c
@@ -58,6 +58,7 @@ ip_init(Slirp *slirp)
     slirp->ipq.ip_link.next = slirp->ipq.ip_link.prev = &slirp->ipq.ip_link;
     udp_init(slirp);
     tcp_init(slirp);
+    icmp_init(slirp);
 }
 
 /*
diff --git a/slirp/misc.c b/slirp/misc.c
index 34179e2..6002550 100644
--- a/slirp/misc.c
+++ b/slirp/misc.c
@@ -407,4 +407,17 @@ void slirp_connection_info(Slirp *slirp, Monitor *mon)
                        inet_ntoa(dst_addr), ntohs(dst_port),
                        so->so_rcv.sb_cc, so->so_snd.sb_cc);
     }
+
+    for (so = slirp->icmp.so_next; so != &slirp->icmp; so = so->so_next) {
+        n = snprintf(buf, sizeof(buf), "  ICMP[%d sec]",
+                     (so->so_expire - curtime) / 1000);
+        src.sin_addr = so->so_laddr;
+        dst_addr = so->so_faddr;
+        memset(&buf[n], ' ', 19 - n);
+        buf[19] = 0;
+        monitor_printf(mon, "%s %3d %15s  -    ", buf, so->s,
+                       src.sin_addr.s_addr ? inet_ntoa(src.sin_addr) : "*");
+        monitor_printf(mon, "%15s  -    %5d %5d\n", inet_ntoa(dst_addr),
+                       so->so_rcv.sb_cc, so->so_snd.sb_cc);
+    }
 }
diff --git a/slirp/slirp.c b/slirp/slirp.c
index 1593be1..faaa2f3 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -373,6 +373,31 @@ void slirp_select_fill(int *pnfds,
 				UPD_NFDS(so->s);
 			}
 		}
+
+                /*
+                 * ICMP sockets
+                 */
+                for (so = slirp->icmp.so_next; so != &slirp->icmp;
+                     so = so_next) {
+                    so_next = so->so_next;
+
+                    /*
+                     * See if it's timed out
+                     */
+                    if (so->so_expire) {
+                        if (so->so_expire <= curtime) {
+                            icmp_detach(so);
+                            continue;
+                        } else {
+                            do_slowtimo = 1; /* Let socket expire */
+                        }
+                    }
+
+                    if (so->so_state & SS_ISFCONNECTED) {
+                        FD_SET(so->s, readfds);
+                        UPD_NFDS(so->s);
+                    }
+                }
 	}
 
         *pnfds = nfds;
@@ -542,6 +567,18 @@ void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds,
                             sorecvfrom(so);
                         }
 		}
+
+                /*
+                 * Check incoming ICMP relies.
+                 */
+                for (so = slirp->icmp.so_next; so != &slirp->icmp;
+                     so = so_next) {
+                     so_next = so->so_next;
+
+                    if (so->s != -1 && FD_ISSET(so->s, readfds)) {
+                        icmp_receive(so);
+                    }
+                }
 	}
 
 	/*
diff --git a/slirp/slirp.h b/slirp/slirp.h
index 954289a..16bb6ba 100644
--- a/slirp/slirp.h
+++ b/slirp/slirp.h
@@ -152,6 +152,7 @@ int inet_aton(const char *cp, struct in_addr *ia);
 #include "tcp_var.h"
 #include "tcpip.h"
 #include "udp.h"
+#include "ip_icmp.h"
 #include "mbuf.h"
 #include "sbuf.h"
 #include "socket.h"
@@ -218,6 +219,10 @@ struct Slirp {
     struct socket udb;
     struct socket *udp_last_so;
 
+    /* icmp states */
+    struct socket icmp;
+    struct socket *icmp_last_so;
+
     /* tftp states */
     char *tftp_prefix;
     struct tftp_session tftp_sessions[TFTP_SESSIONS_MAX];
diff --git a/slirp/socket.c b/slirp/socket.c
index 6119234..9b8ae13 100644
--- a/slirp/socket.c
+++ b/slirp/socket.c
@@ -71,6 +71,8 @@ sofree(struct socket *so)
       slirp->tcp_last_so = &slirp->tcb;
   } else if (so == slirp->udp_last_so) {
       slirp->udp_last_so = &slirp->udb;
+  } else if (so == slirp->icmp_last_so) {
+      slirp->icmp_last_so = &slirp->icmp;
   }
   m_free(so->so_m);
 
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [Qemu-devel] [PATCH 07/10] net: Improve layout of 'info network'
  2011-07-20 10:20 [Qemu-devel] [PATCH 00/10] [RESEND] Various net and slirp fixes & enhancements Jan Kiszka
                   ` (5 preceding siblings ...)
  2011-07-20 10:20 ` [Qemu-devel] [PATCH 06/10] slirp: Forward ICMP echo requests via unprivileged sockets Jan Kiszka
@ 2011-07-20 10:20 ` Jan Kiszka
  2011-07-20 10:20 ` [Qemu-devel] [PATCH 08/10] net: Refactor net_client_types Jan Kiszka
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Jan Kiszka @ 2011-07-20 10:20 UTC (permalink / raw)
  To: Anthony Liguori, qemu-devel; +Cc: Markus Armbruster

Improve the layout when listing non-vlan clients via 'info network'. The
result looks like this:

(qemu) info network
Devices not on any VLAN:
  orphan: net=10.0.2.0, restricted=n
  virtio-net-pci.0: model=virtio-net-pci,macaddr=52:54:00:12:34:56
   \ network2: fd=5
  e1000.0: model=e1000,macaddr=52:54:00:12:34:57
   \ network1: net=10.0.2.0, restricted=n
  rtl8139.0: model=rtl8139,macaddr=52:54:00:12:34:58

ie. peers are grouped, orphans are listed as before.

CC: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 net.c |   14 +++++++++-----
 1 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/net.c b/net.c
index 66123ad..43627ad 100644
--- a/net.c
+++ b/net.c
@@ -1224,7 +1224,8 @@ int do_netdev_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
 void do_info_network(Monitor *mon)
 {
     VLANState *vlan;
-    VLANClientState *vc;
+    VLANClientState *vc, *peer;
+    net_client_type type;
 
     QTAILQ_FOREACH(vlan, &vlans, next) {
         monitor_printf(mon, "VLAN %d devices:\n", vlan->id);
@@ -1235,11 +1236,14 @@ void do_info_network(Monitor *mon)
     }
     monitor_printf(mon, "Devices not on any VLAN:\n");
     QTAILQ_FOREACH(vc, &non_vlan_clients, next) {
-        monitor_printf(mon, "  %s: %s", vc->name, vc->info_str);
-        if (vc->peer) {
-            monitor_printf(mon, " peer=%s", vc->peer->name);
+        peer = vc->peer;
+        type = vc->info->type;
+        if (!peer || type == NET_CLIENT_TYPE_NIC) {
+            monitor_printf(mon, "  %s: %s\n", vc->name, vc->info_str);
+        } /* else it's a netdev connected to a NIC, printed with the NIC */
+        if (peer && type == NET_CLIENT_TYPE_NIC) {
+            monitor_printf(mon, "   \\ %s: %s\n", peer->name, peer->info_str);
         }
-        monitor_printf(mon, "\n");
     }
 }
 
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [Qemu-devel] [PATCH 08/10] net: Refactor net_client_types
  2011-07-20 10:20 [Qemu-devel] [PATCH 00/10] [RESEND] Various net and slirp fixes & enhancements Jan Kiszka
                   ` (6 preceding siblings ...)
  2011-07-20 10:20 ` [Qemu-devel] [PATCH 07/10] net: Improve layout of 'info network' Jan Kiszka
@ 2011-07-20 10:20 ` Jan Kiszka
  2011-07-20 10:20 ` [Qemu-devel] [PATCH 09/10] net: Dump client type 'info network' Jan Kiszka
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Jan Kiszka @ 2011-07-20 10:20 UTC (permalink / raw)
  To: Anthony Liguori, qemu-devel; +Cc: Markus Armbruster

Position entries of net_client_types according to the corresponding
values of NET_CLIENT_TYPE_*. The array size is now defined by
NET_CLIENT_TYPE_MAX. This will allow to obtain entries based on type
value in later patches.

At this chance rename NET_CLIENT_TYPE_SLIRP to NET_CLIENT_TYPE_USER for
the sake of consistency.

CC: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 net.c       |   30 ++++++++++++++++++------------
 net.h       |    6 ++++--
 net/slirp.c |    2 +-
 3 files changed, 23 insertions(+), 15 deletions(-)

diff --git a/net.c b/net.c
index 43627ad..05fc685 100644
--- a/net.c
+++ b/net.c
@@ -830,14 +830,15 @@ static const struct {
     const char *type;
     net_client_init_func init;
     QemuOptDesc desc[NET_MAX_DESC];
-} net_client_types[] = {
-    {
+} net_client_types[NET_CLIENT_TYPE_MAX] = {
+    [NET_CLIENT_TYPE_NONE] = {
         .type = "none",
         .desc = {
             NET_COMMON_PARAMS_DESC,
             { /* end of list */ }
         },
-    }, {
+    },
+    [NET_CLIENT_TYPE_NIC] = {
         .type = "nic",
         .init = net_init_nic,
         .desc = {
@@ -866,8 +867,9 @@ static const struct {
             },
             { /* end of list */ }
         },
+    },
 #ifdef CONFIG_SLIRP
-    }, {
+    [NET_CLIENT_TYPE_USER] = {
         .type = "user",
         .init = net_init_slirp,
         .desc = {
@@ -927,8 +929,9 @@ static const struct {
             },
             { /* end of list */ }
         },
+    },
 #endif
-    }, {
+    [NET_CLIENT_TYPE_TAP] = {
         .type = "tap",
         .init = net_init_tap,
         .desc = {
@@ -975,7 +978,8 @@ static const struct {
 #endif /* _WIN32 */
             { /* end of list */ }
         },
-    }, {
+    },
+    [NET_CLIENT_TYPE_SOCKET] = {
         .type = "socket",
         .init = net_init_socket,
         .desc = {
@@ -1003,8 +1007,9 @@ static const struct {
             },
             { /* end of list */ }
         },
+    },
 #ifdef CONFIG_VDE
-    }, {
+    [NET_CLIENT_TYPE_VDE] = {
         .type = "vde",
         .init = net_init_vde,
         .desc = {
@@ -1028,8 +1033,9 @@ static const struct {
             },
             { /* end of list */ }
         },
+    },
 #endif
-    }, {
+    [NET_CLIENT_TYPE_DUMP] = {
         .type = "dump",
         .init = net_init_dump,
         .desc = {
@@ -1046,7 +1052,6 @@ static const struct {
             { /* end of list */ }
         },
     },
-    { /* end of list */ }
 };
 
 int net_client_init(Monitor *mon, QemuOpts *opts, int is_netdev)
@@ -1094,8 +1099,9 @@ int net_client_init(Monitor *mon, QemuOpts *opts, int is_netdev)
         name = qemu_opt_get(opts, "name");
     }
 
-    for (i = 0; net_client_types[i].type != NULL; i++) {
-        if (!strcmp(net_client_types[i].type, type)) {
+    for (i = 0; i < NET_CLIENT_TYPE_MAX; i++) {
+        if (net_client_types[i].type != NULL &&
+            !strcmp(net_client_types[i].type, type)) {
             VLANState *vlan = NULL;
             int ret;
 
@@ -1330,7 +1336,7 @@ void net_check_clients(void)
             case NET_CLIENT_TYPE_NIC:
                 has_nic = 1;
                 break;
-            case NET_CLIENT_TYPE_SLIRP:
+            case NET_CLIENT_TYPE_USER:
             case NET_CLIENT_TYPE_TAP:
             case NET_CLIENT_TYPE_SOCKET:
             case NET_CLIENT_TYPE_VDE:
diff --git a/net.h b/net.h
index 5b883a9..4fdd942 100644
--- a/net.h
+++ b/net.h
@@ -31,11 +31,13 @@ typedef struct NICConf {
 typedef enum {
     NET_CLIENT_TYPE_NONE,
     NET_CLIENT_TYPE_NIC,
-    NET_CLIENT_TYPE_SLIRP,
+    NET_CLIENT_TYPE_USER,
     NET_CLIENT_TYPE_TAP,
     NET_CLIENT_TYPE_SOCKET,
     NET_CLIENT_TYPE_VDE,
-    NET_CLIENT_TYPE_DUMP
+    NET_CLIENT_TYPE_DUMP,
+
+    NET_CLIENT_TYPE_MAX
 } net_client_type;
 
 typedef void (NetPoll)(VLANClientState *, bool enable);
diff --git a/net/slirp.c b/net/slirp.c
index 71e2577..157b80a 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -128,7 +128,7 @@ static void net_slirp_cleanup(VLANClientState *nc)
 }
 
 static NetClientInfo net_slirp_info = {
-    .type = NET_CLIENT_TYPE_SLIRP,
+    .type = NET_CLIENT_TYPE_USER,
     .size = sizeof(SlirpState),
     .receive = net_slirp_receive,
     .cleanup = net_slirp_cleanup,
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [Qemu-devel] [PATCH 09/10] net: Dump client type 'info network'
  2011-07-20 10:20 [Qemu-devel] [PATCH 00/10] [RESEND] Various net and slirp fixes & enhancements Jan Kiszka
                   ` (7 preceding siblings ...)
  2011-07-20 10:20 ` [Qemu-devel] [PATCH 08/10] net: Refactor net_client_types Jan Kiszka
@ 2011-07-20 10:20 ` Jan Kiszka
  2011-07-20 10:20 ` [Qemu-devel] [PATCH 10/10] net: Consistently use qemu_macaddr_default_if_unset Jan Kiszka
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 13+ messages in thread
From: Jan Kiszka @ 2011-07-20 10:20 UTC (permalink / raw)
  To: Anthony Liguori, qemu-devel; +Cc: Markus Armbruster

Include the client type name into the output of 'info network'. The
result looks like this:

(qemu) info network
VLAN 0 devices:
  rtl8139.0: type=nic,model=rtl8139,macaddr=52:54:00:12:34:57
Devices not on any VLAN:
  virtio-net-pci.0: type=nic,model=virtio-net-pci,macaddr=52:54:00:12:34:56
   \ network1: type=tap,fd=5

CC: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 net.c |   15 ++++++++++++---
 1 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/net.c b/net.c
index 05fc685..12701af 100644
--- a/net.c
+++ b/net.c
@@ -1227,6 +1227,12 @@ int do_netdev_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
     return 0;
 }
 
+static void print_net_client(Monitor *mon, VLANClientState *vc)
+{
+    monitor_printf(mon, "%s: type=%s,%s\n", vc->name,
+                   net_client_types[vc->info->type].type, vc->info_str);
+}
+
 void do_info_network(Monitor *mon)
 {
     VLANState *vlan;
@@ -1237,7 +1243,8 @@ void do_info_network(Monitor *mon)
         monitor_printf(mon, "VLAN %d devices:\n", vlan->id);
 
         QTAILQ_FOREACH(vc, &vlan->clients, next) {
-            monitor_printf(mon, "  %s: %s\n", vc->name, vc->info_str);
+            monitor_printf(mon, "  ");
+            print_net_client(mon, vc);
         }
     }
     monitor_printf(mon, "Devices not on any VLAN:\n");
@@ -1245,10 +1252,12 @@ void do_info_network(Monitor *mon)
         peer = vc->peer;
         type = vc->info->type;
         if (!peer || type == NET_CLIENT_TYPE_NIC) {
-            monitor_printf(mon, "  %s: %s\n", vc->name, vc->info_str);
+            monitor_printf(mon, "  ");
+            print_net_client(mon, vc);
         } /* else it's a netdev connected to a NIC, printed with the NIC */
         if (peer && type == NET_CLIENT_TYPE_NIC) {
-            monitor_printf(mon, "   \\ %s: %s\n", peer->name, peer->info_str);
+            monitor_printf(mon, "   \\ ");
+            print_net_client(mon, peer);
         }
     }
 }
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [Qemu-devel] [PATCH 10/10] net: Consistently use qemu_macaddr_default_if_unset
  2011-07-20 10:20 [Qemu-devel] [PATCH 00/10] [RESEND] Various net and slirp fixes & enhancements Jan Kiszka
                   ` (8 preceding siblings ...)
  2011-07-20 10:20 ` [Qemu-devel] [PATCH 09/10] net: Dump client type 'info network' Jan Kiszka
@ 2011-07-20 10:20 ` Jan Kiszka
  2011-07-22 14:31 ` [Qemu-devel] [PATCH 00/10] [RESEND] Various net and slirp fixes & enhancements Markus Armbruster
  2011-07-23 15:45 ` Anthony Liguori
  11 siblings, 0 replies; 13+ messages in thread
From: Jan Kiszka @ 2011-07-20 10:20 UTC (permalink / raw)
  To: Anthony Liguori, qemu-devel; +Cc: Peter Maydell, Markus Armbruster

Drop the open-coded MAC assignment from net_init_nic and replace it with
standard qemu_macaddr_default_if_unset which is also used by qdev. That
avoid creating colliding MACs when instantiating NICs via different
mechanisms.

This change requires to store the MAC as MACAddr in NICInfo, and the
remaining nd_table users need to be updated.

Based on suggestion by Peter Maydell.

CC: Markus Armbruster <armbru@redhat.com>
CC: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 hw/dp8393x.c       |    2 +-
 hw/etraxfs_eth.c   |    2 +-
 hw/mcf_fec.c       |    2 +-
 hw/mipsnet.c       |    2 +-
 hw/qdev.c          |    2 +-
 hw/stellaris.c     |    2 +-
 hw/xen_devconfig.c |    4 ++--
 net.c              |   10 ++--------
 net.h              |    2 +-
 9 files changed, 11 insertions(+), 17 deletions(-)

diff --git a/hw/dp8393x.c b/hw/dp8393x.c
index c332dd5..1bcd8ee 100644
--- a/hw/dp8393x.c
+++ b/hw/dp8393x.c
@@ -898,7 +898,7 @@ void dp83932_init(NICInfo *nd, target_phys_addr_t base, int it_shift,
     s->watchdog = qemu_new_timer_ns(vm_clock, dp8393x_watchdog, s);
     s->regs[SONIC_SR] = 0x0004; /* only revision recognized by Linux */
 
-    memcpy(s->conf.macaddr.a, nd->macaddr, sizeof(s->conf.macaddr));
+    s->conf.macaddr = nd->macaddr;
     s->conf.vlan = nd->vlan;
     s->conf.peer = nd->netdev;
 
diff --git a/hw/etraxfs_eth.c b/hw/etraxfs_eth.c
index 6aa4007..dff5f55 100644
--- a/hw/etraxfs_eth.c
+++ b/hw/etraxfs_eth.c
@@ -602,7 +602,7 @@ void *etraxfs_eth_init(NICInfo *nd, target_phys_addr_t base, int phyaddr)
                                               DEVICE_NATIVE_ENDIAN);
 	cpu_register_physical_memory (base, 0x5c, eth->ethregs);
 
-	memcpy(eth->conf.macaddr.a, nd->macaddr, sizeof(nd->macaddr));
+	eth->conf.macaddr = nd->macaddr;
 	eth->conf.vlan = nd->vlan;
 	eth->conf.peer = nd->netdev;
 
diff --git a/hw/mcf_fec.c b/hw/mcf_fec.c
index 21035da..5477e0e 100644
--- a/hw/mcf_fec.c
+++ b/hw/mcf_fec.c
@@ -471,7 +471,7 @@ void mcf_fec_init(NICInfo *nd, target_phys_addr_t base, qemu_irq *irq)
                                            DEVICE_NATIVE_ENDIAN);
     cpu_register_physical_memory(base, 0x400, s->mmio_index);
 
-    memcpy(s->conf.macaddr.a, nd->macaddr, sizeof(nd->macaddr));
+    s->conf.macaddr = nd->macaddr;
     s->conf.vlan = nd->vlan;
     s->conf.peer = nd->netdev;
 
diff --git a/hw/mipsnet.c b/hw/mipsnet.c
index 26aad51..0db3ba7 100644
--- a/hw/mipsnet.c
+++ b/hw/mipsnet.c
@@ -258,7 +258,7 @@ void mipsnet_init (int base, qemu_irq irq, NICInfo *nd)
     s->irq = irq;
 
     if (nd) {
-        memcpy(s->conf.macaddr.a, nd->macaddr, sizeof(nd->macaddr));
+        s->conf.macaddr = nd->macaddr;
         s->conf.vlan = nd->vlan;
         s->conf.peer = nd->netdev;
 
diff --git a/hw/qdev.c b/hw/qdev.c
index 292b52f..a0fcd06 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -459,7 +459,7 @@ void qdev_connect_gpio_out(DeviceState * dev, int n, qemu_irq pin)
 
 void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd)
 {
-    qdev_prop_set_macaddr(dev, "mac", nd->macaddr);
+    qdev_prop_set_macaddr(dev, "mac", nd->macaddr.a);
     if (nd->vlan)
         qdev_prop_set_vlan(dev, "vlan", nd->vlan);
     if (nd->netdev)
diff --git a/hw/stellaris.c b/hw/stellaris.c
index ac9fcc1..b8a7ceb 100644
--- a/hw/stellaris.c
+++ b/hw/stellaris.c
@@ -1230,7 +1230,7 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model,
         }
     }
 
-    stellaris_sys_init(0x400fe000, pic[28], board, nd_table[0].macaddr);
+    stellaris_sys_init(0x400fe000, pic[28], board, nd_table[0].macaddr.a);
 
     for (i = 0; i < 7; i++) {
         if (board->dc4 & (1 << i)) {
diff --git a/hw/xen_devconfig.c b/hw/xen_devconfig.c
index 3a92155..6926c54 100644
--- a/hw/xen_devconfig.c
+++ b/hw/xen_devconfig.c
@@ -126,8 +126,8 @@ int xen_config_dev_nic(NICInfo *nic)
     char mac[20];
 
     snprintf(mac, sizeof(mac), "%02x:%02x:%02x:%02x:%02x:%02x",
-	     nic->macaddr[0], nic->macaddr[1], nic->macaddr[2],
-	     nic->macaddr[3], nic->macaddr[4], nic->macaddr[5]);
+             nic->macaddr.a[0], nic->macaddr.a[1], nic->macaddr.a[2],
+             nic->macaddr.a[3], nic->macaddr.a[4], nic->macaddr.a[5]);
     xen_be_printf(NULL, 1, "config nic %d: mac=\"%s\"\n", nic->vlan->id, mac);
     xen_config_dev_dirs("vif", "qnic", nic->vlan->id, fe, be, sizeof(fe));
 
diff --git a/net.c b/net.c
index 12701af..31c2338 100644
--- a/net.c
+++ b/net.c
@@ -776,18 +776,12 @@ static int net_init_nic(QemuOpts *opts,
         nd->devaddr = qemu_strdup(qemu_opt_get(opts, "addr"));
     }
 
-    nd->macaddr[0] = 0x52;
-    nd->macaddr[1] = 0x54;
-    nd->macaddr[2] = 0x00;
-    nd->macaddr[3] = 0x12;
-    nd->macaddr[4] = 0x34;
-    nd->macaddr[5] = 0x56 + idx;
-
     if (qemu_opt_get(opts, "macaddr") &&
-        net_parse_macaddr(nd->macaddr, qemu_opt_get(opts, "macaddr")) < 0) {
+        net_parse_macaddr(nd->macaddr.a, qemu_opt_get(opts, "macaddr")) < 0) {
         error_report("invalid syntax for ethernet address");
         return -1;
     }
+    qemu_macaddr_default_if_unset(&nd->macaddr);
 
     nd->nvectors = qemu_opt_get_number(opts, "vectors",
                                        DEV_NVECTORS_UNSPECIFIED);
diff --git a/net.h b/net.h
index 4fdd942..5a7881c 100644
--- a/net.h
+++ b/net.h
@@ -129,7 +129,7 @@ int do_set_link(Monitor *mon, const QDict *qdict, QObject **ret_data);
 #define MAX_NICS 8
 
 struct NICInfo {
-    uint8_t macaddr[6];
+    MACAddr macaddr;
     char *model;
     char *name;
     char *devaddr;
-- 
1.7.3.4

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [Qemu-devel] [PATCH 00/10] [RESEND] Various net and slirp fixes & enhancements
  2011-07-20 10:20 [Qemu-devel] [PATCH 00/10] [RESEND] Various net and slirp fixes & enhancements Jan Kiszka
                   ` (9 preceding siblings ...)
  2011-07-20 10:20 ` [Qemu-devel] [PATCH 10/10] net: Consistently use qemu_macaddr_default_if_unset Jan Kiszka
@ 2011-07-22 14:31 ` Markus Armbruster
  2011-07-23 15:45 ` Anthony Liguori
  11 siblings, 0 replies; 13+ messages in thread
From: Markus Armbruster @ 2011-07-22 14:31 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: Peter Maydell, Anthony Liguori, qemu-devel, Gleb Natapov

Jan Kiszka <jan.kiszka@siemens.com> writes:

> Almost just a reposting of the previously sent series. No patch
> modified, but a nifty (IMO) new one: ping forwarding for slirp using
> the unprivileged ICMP sockets of Linux 3.0. See commit log for a simple
> how-to.

My positive review of the previous version of 07-10 (posted on June 8)
should still apply.  Please apply.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [Qemu-devel] [PATCH 00/10] [RESEND] Various net and slirp fixes & enhancements
  2011-07-20 10:20 [Qemu-devel] [PATCH 00/10] [RESEND] Various net and slirp fixes & enhancements Jan Kiszka
                   ` (10 preceding siblings ...)
  2011-07-22 14:31 ` [Qemu-devel] [PATCH 00/10] [RESEND] Various net and slirp fixes & enhancements Markus Armbruster
@ 2011-07-23 15:45 ` Anthony Liguori
  11 siblings, 0 replies; 13+ messages in thread
From: Anthony Liguori @ 2011-07-23 15:45 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: Peter Maydell, qemu-devel, Gleb Natapov, Markus Armbruster

On 07/20/2011 05:20 AM, Jan Kiszka wrote:
> Almost just a reposting of the previously sent series. No patch
> modified, but a nifty (IMO) new one: ping forwarding for slirp using
> the unprivileged ICMP sockets of Linux 3.0. See commit log for a simple
> how-to.
>
> CC: Gleb Natapov<gleb@redhat.com>
> CC: Markus Armbruster<armbru@redhat.com>
> CC: Peter Maydell<peter.maydell@linaro.org>

Applied.  Thanks.

The ICMP sockets thing is pretty cool!

Regards,

Anthony Liguori

>
> Jan Kiszka (10):
>    slirp: Fix restricted mode
>    slirp: Canonicalize restrict syntax
>    slirp: Strictly associate DHCP/BOOTP and TFTP with virtual host
>    slirp: Replace m_freem with m_free
>    slirp: Put forked exec into separate process group
>    slirp: Forward ICMP echo requests via unprivileged sockets
>    net: Improve layout of 'info network'
>    net: Refactor net_client_types
>    net: Dump client type 'info network'
>    net: Consistently use qemu_macaddr_default_if_unset
>
>   hw/dp8393x.c       |    2 +-
>   hw/etraxfs_eth.c   |    2 +-
>   hw/mcf_fec.c       |    2 +-
>   hw/mipsnet.c       |    2 +-
>   hw/qdev.c          |    2 +-
>   hw/stellaris.c     |    2 +-
>   hw/xen_devconfig.c |    4 +-
>   net.c              |   65 +++++++++++++++++++++--------------
>   net.h              |    8 +++--
>   net/slirp.c        |   23 +++++++++----
>   qemu-options.hx    |    4 +-
>   slirp/ip_icmp.c    |   95 +++++++++++++++++++++++++++++++++++++++++++++++++--
>   slirp/ip_icmp.h    |    3 ++
>   slirp/ip_input.c   |   30 +++--------------
>   slirp/ip_output.c  |    4 +-
>   slirp/mbuf.h       |    3 --
>   slirp/misc.c       |   16 ++++++++-
>   slirp/slirp.c      |   37 ++++++++++++++++++++
>   slirp/slirp.h      |    5 +++
>   slirp/socket.c     |    2 +
>   slirp/tcp_input.c  |   10 +++---
>   slirp/tcp_subr.c   |    2 +-
>   slirp/udp.c        |   23 +++++++-----
>   23 files changed, 249 insertions(+), 97 deletions(-)
>

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2011-07-23 15:45 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-07-20 10:20 [Qemu-devel] [PATCH 00/10] [RESEND] Various net and slirp fixes & enhancements Jan Kiszka
2011-07-20 10:20 ` [Qemu-devel] [PATCH 01/10] slirp: Fix restricted mode Jan Kiszka
2011-07-20 10:20 ` [Qemu-devel] [PATCH 02/10] slirp: Canonicalize restrict syntax Jan Kiszka
2011-07-20 10:20 ` [Qemu-devel] [PATCH 03/10] slirp: Strictly associate DHCP/BOOTP and TFTP with virtual host Jan Kiszka
2011-07-20 10:20 ` [Qemu-devel] [PATCH 04/10] slirp: Replace m_freem with m_free Jan Kiszka
2011-07-20 10:20 ` [Qemu-devel] [PATCH 05/10] slirp: Put forked exec into separate process group Jan Kiszka
2011-07-20 10:20 ` [Qemu-devel] [PATCH 06/10] slirp: Forward ICMP echo requests via unprivileged sockets Jan Kiszka
2011-07-20 10:20 ` [Qemu-devel] [PATCH 07/10] net: Improve layout of 'info network' Jan Kiszka
2011-07-20 10:20 ` [Qemu-devel] [PATCH 08/10] net: Refactor net_client_types Jan Kiszka
2011-07-20 10:20 ` [Qemu-devel] [PATCH 09/10] net: Dump client type 'info network' Jan Kiszka
2011-07-20 10:20 ` [Qemu-devel] [PATCH 10/10] net: Consistently use qemu_macaddr_default_if_unset Jan Kiszka
2011-07-22 14:31 ` [Qemu-devel] [PATCH 00/10] [RESEND] Various net and slirp fixes & enhancements Markus Armbruster
2011-07-23 15:45 ` Anthony Liguori

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).