[Qemu-devel] [PULL 1/2] slirp: fill error when failing to initialize user network

2017-08-02 Thread Samuel Thibault
From: Hervé Poussineau 

With "-netdev user,id=net0,dns=1.2.3.4"
error was:
qemu-system-i386: -netdev user,id=net0,dns=1.2.3.4: Device 'user' could not be 
initialized

Error is now:
qemu-system-i386: -netdev user,id=net0,dns=1.2.3.4: DNS doesn't belong to 
network

Signed-off-by: Hervé Poussineau 
Signed-off-by: Samuel Thibault 
---
 net/slirp.c | 134 ++--
 1 file changed, 94 insertions(+), 40 deletions(-)

diff --git a/net/slirp.c b/net/slirp.c
index 9fbc949e81..01ed21c006 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -91,15 +91,15 @@ static QTAILQ_HEAD(slirp_stacks, SlirpState) slirp_stacks =
 QTAILQ_HEAD_INITIALIZER(slirp_stacks);
 
 static int slirp_hostfwd(SlirpState *s, const char *redir_str,
- int legacy_format);
+ int legacy_format, Error **errp);
 static int slirp_guestfwd(SlirpState *s, const char *config_str,
-  int legacy_format);
+  int legacy_format, Error **errp);
 
 #ifndef _WIN32
 static const char *legacy_smb_export;
 
 static int slirp_smb(SlirpState *s, const char *exported_dir,
- struct in_addr vserver_addr);
+ struct in_addr vserver_addr, Error **errp);
 static void slirp_smb_cleanup(SlirpState *s);
 #else
 static inline void slirp_smb_cleanup(SlirpState *s) { }
@@ -155,7 +155,7 @@ static int net_slirp_init(NetClientState *peer, const char 
*model,
   const char *bootfile, const char *vdhcp_start,
   const char *vnameserver, const char *vnameserver6,
   const char *smb_export, const char *vsmbserver,
-  const char **dnssearch)
+  const char **dnssearch, Error **errp)
 {
 /* default settings according to historic slirp */
 struct in_addr net  = { .s_addr = htonl(0x0a000200) }; /* 10.0.2.0 */
@@ -178,15 +178,18 @@ static int net_slirp_init(NetClientState *peer, const 
char *model,
 struct slirp_config_str *config;
 
 if (!ipv4 && (vnetwork || vhost || vnameserver)) {
+error_setg(errp, "IPv4 disabled but netmask/host/dns provided");
 return -1;
 }
 
 if (!ipv6 && (vprefix6 || vhost6 || vnameserver6)) {
+error_setg(errp, "IPv6 disabled but prefix/host6/dns6 provided");
 return -1;
 }
 
 if (!ipv4 && !ipv6) {
 /* It doesn't make sense to disable both */
+error_setg(errp, "IPv4 and IPv6 disabled");
 return -1;
 }
 
@@ -200,6 +203,7 @@ static int net_slirp_init(NetClientState *peer, const char 
*model,
 if (vnetwork) {
 if (get_str_sep(buf, sizeof(buf), , '/') < 0) {
 if (!inet_aton(vnetwork, )) {
+error_setg(errp, "Failed to parse netmask");
 return -1;
 }
 addr = ntohl(net.s_addr);
@@ -220,14 +224,19 @@ static int net_slirp_init(NetClientState *peer, const 
char *model,
 }
 } else {
 if (!inet_aton(buf, )) {
+error_setg(errp, "Failed to parse netmask");
 return -1;
 }
 shift = strtol(vnetwork, , 10);
 if (*end != '\0') {
 if (!inet_aton(vnetwork, )) {
+error_setg(errp,
+   "Failed to parse netmask (trailing chars)");
 return -1;
 }
 } else if (shift < 4 || shift > 32) {
+error_setg(errp,
+   "Invalid netmask provided (must be in range 4-32)");
 return -1;
 } else {
 mask.s_addr = htonl(0x << (32 - shift));
@@ -240,30 +249,43 @@ static int net_slirp_init(NetClientState *peer, const 
char *model,
 }
 
 if (vhost && !inet_aton(vhost, )) {
+error_setg(errp, "Failed to parse host");
 return -1;
 }
 if ((host.s_addr & mask.s_addr) != net.s_addr) {
+error_setg(errp, "Host doesn't belong to network");
 return -1;
 }
 
 if (vnameserver && !inet_aton(vnameserver, )) {
+error_setg(errp, "Failed to parse DNS");
 return -1;
 }
-if ((dns.s_addr & mask.s_addr) != net.s_addr ||
-dns.s_addr == host.s_addr) {
+if ((dns.s_addr & mask.s_addr) != net.s_addr) {
+error_setg(errp, "DNS doesn't belong to network");
+return -1;
+}
+if (dns.s_addr == host.s_addr) {
+error_setg(errp, "DNS must be different from host");
 return -1;
 }
 
 if (vdhcp_start && !inet_aton(vdhcp_start, )) {
+error_setg(errp, "Failed to parse DHCP start address");
 return -1;
 }
-if ((dhcp.s_addr & mask.s_addr) != net.s_addr ||
-dhcp.s_addr == host.s_addr || dhcp.s_addr == dns.s_addr) {
+if ((dhcp.s_addr & 

[Qemu-devel] [PULL 1/2] slirp: fill error when failing to initialize user network

2017-08-02 Thread Samuel Thibault
From: Hervé Poussineau 

With "-netdev user,id=net0,dns=1.2.3.4"
error was:
qemu-system-i386: -netdev user,id=net0,dns=1.2.3.4: Device 'user' could not be 
initialized

Error is now:
qemu-system-i386: -netdev user,id=net0,dns=1.2.3.4: DNS doesn't belong to 
network

Signed-off-by: Hervé Poussineau 
Signed-off-by: Samuel Thibault 
---
 net/slirp.c | 134 ++--
 1 file changed, 94 insertions(+), 40 deletions(-)

diff --git a/net/slirp.c b/net/slirp.c
index 9fbc949e81..01ed21c006 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -91,15 +91,15 @@ static QTAILQ_HEAD(slirp_stacks, SlirpState) slirp_stacks =
 QTAILQ_HEAD_INITIALIZER(slirp_stacks);
 
 static int slirp_hostfwd(SlirpState *s, const char *redir_str,
- int legacy_format);
+ int legacy_format, Error **errp);
 static int slirp_guestfwd(SlirpState *s, const char *config_str,
-  int legacy_format);
+  int legacy_format, Error **errp);
 
 #ifndef _WIN32
 static const char *legacy_smb_export;
 
 static int slirp_smb(SlirpState *s, const char *exported_dir,
- struct in_addr vserver_addr);
+ struct in_addr vserver_addr, Error **errp);
 static void slirp_smb_cleanup(SlirpState *s);
 #else
 static inline void slirp_smb_cleanup(SlirpState *s) { }
@@ -155,7 +155,7 @@ static int net_slirp_init(NetClientState *peer, const char 
*model,
   const char *bootfile, const char *vdhcp_start,
   const char *vnameserver, const char *vnameserver6,
   const char *smb_export, const char *vsmbserver,
-  const char **dnssearch)
+  const char **dnssearch, Error **errp)
 {
 /* default settings according to historic slirp */
 struct in_addr net  = { .s_addr = htonl(0x0a000200) }; /* 10.0.2.0 */
@@ -178,15 +178,18 @@ static int net_slirp_init(NetClientState *peer, const 
char *model,
 struct slirp_config_str *config;
 
 if (!ipv4 && (vnetwork || vhost || vnameserver)) {
+error_setg(errp, "IPv4 disabled but netmask/host/dns provided");
 return -1;
 }
 
 if (!ipv6 && (vprefix6 || vhost6 || vnameserver6)) {
+error_setg(errp, "IPv6 disabled but prefix/host6/dns6 provided");
 return -1;
 }
 
 if (!ipv4 && !ipv6) {
 /* It doesn't make sense to disable both */
+error_setg(errp, "IPv4 and IPv6 disabled");
 return -1;
 }
 
@@ -200,6 +203,7 @@ static int net_slirp_init(NetClientState *peer, const char 
*model,
 if (vnetwork) {
 if (get_str_sep(buf, sizeof(buf), , '/') < 0) {
 if (!inet_aton(vnetwork, )) {
+error_setg(errp, "Failed to parse netmask");
 return -1;
 }
 addr = ntohl(net.s_addr);
@@ -220,14 +224,19 @@ static int net_slirp_init(NetClientState *peer, const 
char *model,
 }
 } else {
 if (!inet_aton(buf, )) {
+error_setg(errp, "Failed to parse netmask");
 return -1;
 }
 shift = strtol(vnetwork, , 10);
 if (*end != '\0') {
 if (!inet_aton(vnetwork, )) {
+error_setg(errp,
+   "Failed to parse netmask (trailing chars)");
 return -1;
 }
 } else if (shift < 4 || shift > 32) {
+error_setg(errp,
+   "Invalid netmask provided (must be in range 4-32)");
 return -1;
 } else {
 mask.s_addr = htonl(0x << (32 - shift));
@@ -240,30 +249,43 @@ static int net_slirp_init(NetClientState *peer, const 
char *model,
 }
 
 if (vhost && !inet_aton(vhost, )) {
+error_setg(errp, "Failed to parse host");
 return -1;
 }
 if ((host.s_addr & mask.s_addr) != net.s_addr) {
+error_setg(errp, "Host doesn't belong to network");
 return -1;
 }
 
 if (vnameserver && !inet_aton(vnameserver, )) {
+error_setg(errp, "Failed to parse DNS");
 return -1;
 }
-if ((dns.s_addr & mask.s_addr) != net.s_addr ||
-dns.s_addr == host.s_addr) {
+if ((dns.s_addr & mask.s_addr) != net.s_addr) {
+error_setg(errp, "DNS doesn't belong to network");
+return -1;
+}
+if (dns.s_addr == host.s_addr) {
+error_setg(errp, "DNS must be different from host");
 return -1;
 }
 
 if (vdhcp_start && !inet_aton(vdhcp_start, )) {
+error_setg(errp, "Failed to parse DHCP start address");
 return -1;
 }
-if ((dhcp.s_addr & mask.s_addr) != net.s_addr ||
-dhcp.s_addr == host.s_addr || dhcp.s_addr == dns.s_addr) {
+if ((dhcp.s_addr &