slirp updates (2)

-----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQIcBAABCgAGBQJW/pkpAAoJEOPlHOj7ay8dah0P/AqQ1fly+hNTkhFjpUVGaul1
 uHzxcSuVMuGDrIvpvy+QUnncYOh85rK2Zo8uxF3gpNkoJYGap36l8no/lru6KRSS
 8oYJKkaQ/wdaZlXZEGdtQvL/hlLTg3Z4mCqHoScabu0uEmWoYZ7EOMA0XyyZz2C6
 NhK9khz9ExIWfaLyB+ExUatHIwcLhH3ZPAtOjncewYRUetScwPM826nPTMJeYJoY
 23HFdPZ1KN29fR8gmUyBEMjoplBNGDCw+gRRKVEScPjJVgQ8cHK7AdQrn7sTSINJ
 Tgvg9mScRQMf5Qz6dY3BcKLjkx3Mj1WCV9yUDD1B/SekNu45usYJhWEjLTcFFlM4
 A/b8vgyhuTRwPw6F6sC8h74SDc8IexeRL31pW/1PeVXiLdLvoCow46siibshJrF7
 bFhCcpUro20xykxq2hEyckTM4ECB3unYzsYIaodOmGBWZQj41+I4DcYUScISDpLL
 IJZLzuifA5H7FJbngpI0HVE9EiN9sw+aG4e0zSBZ+QDZijwgu645RGgFixyWCR8U
 UvlG946tP31E/H3bXMBocB1vZekH9puyZnQ+PvGY256n07CgpqFQrvYc9U/ebl23
 zo7rKQF1OBMCXbQh5hQoo1/334dCRSA3sp6uRDk3IVDnmSxt6V7CO3fY1igq3rlW
 WRumRS79G5OZPi95FKzn
 =44Ye
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/thibault/tags/samuel-thibault-2' into staging

slirp updates (2)

# gpg: Signature made Fri 01 Apr 2016 16:52:09 BST using RSA key ID FB6B2F1D
# gpg: Good signature from "Samuel Thibault <samuel.thibault@gnu.org>"
# gpg:                 aka "Samuel Thibault <sthibault@debian.org>"
# gpg:                 aka "Samuel Thibault <samuel.thibault@inria.fr>"
# gpg:                 aka "Samuel Thibault <samuel.thibault@labri.fr>"
# gpg:                 aka "Samuel Thibault <samuel.thibault@ens-lyon.org>"
# gpg: WARNING: This key is not certified with sufficiently trusted signatures!
# gpg:          It is not certain that the signature belongs to the owner.
# Primary key fingerprint: 900C B024 B679 31D4 0F82  304B D017 8C76 7D06 9EE6
#      Subkey fingerprint: F632 74CD C630 0873 CB3D  29D9 E3E5 1CE8 FB6B 2F1D

* remotes/thibault/tags/samuel-thibault-2:
  slirp: Allow disabling IPv4 or IPv6

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2016-04-04 12:09:27 +01:00
commit bdc5db01c3
9 changed files with 74 additions and 10 deletions

View File

@ -136,8 +136,8 @@ static NetClientInfo net_slirp_info = {
static int net_slirp_init(NetClientState *peer, const char *model, static int net_slirp_init(NetClientState *peer, const char *model,
const char *name, int restricted, const char *name, int restricted,
const char *vnetwork, const char *vhost, bool ipv4, const char *vnetwork, const char *vhost,
const char *vprefix6, int vprefix6_len, bool ipv6, const char *vprefix6, int vprefix6_len,
const char *vhost6, const char *vhost6,
const char *vhostname, const char *tftp_export, const char *vhostname, const char *tftp_export,
const char *bootfile, const char *vdhcp_start, const char *bootfile, const char *vdhcp_start,
@ -165,6 +165,19 @@ static int net_slirp_init(NetClientState *peer, const char *model,
char *end; char *end;
struct slirp_config_str *config; struct slirp_config_str *config;
if (!ipv4 && (vnetwork || vhost || vnameserver)) {
return -1;
}
if (!ipv6 && (vprefix6 || vhost6 || vnameserver6)) {
return -1;
}
if (!ipv4 && !ipv6) {
/* It doesn't make sense to disable both */
return -1;
}
if (!tftp_export) { if (!tftp_export) {
tftp_export = legacy_tftp_prefix; tftp_export = legacy_tftp_prefix;
} }
@ -309,8 +322,8 @@ static int net_slirp_init(NetClientState *peer, const char *model,
s = DO_UPCAST(SlirpState, nc, nc); s = DO_UPCAST(SlirpState, nc, nc);
s->slirp = slirp_init(restricted, net, mask, host, s->slirp = slirp_init(restricted, ipv4, net, mask, host,
ip6_prefix, vprefix6_len, ip6_host, ipv6, ip6_prefix, vprefix6_len, ip6_host,
vhostname, tftp_export, bootfile, dhcp, vhostname, tftp_export, bootfile, dhcp,
dns, ip6_dns, dnssearch, s); dns, ip6_dns, dnssearch, s);
QTAILQ_INSERT_TAIL(&slirp_stacks, s, entry); QTAILQ_INSERT_TAIL(&slirp_stacks, s, entry);
@ -813,10 +826,20 @@ int net_init_slirp(const NetClientOptions *opts, const char *name,
int ret; int ret;
const NetdevUserOptions *user; const NetdevUserOptions *user;
const char **dnssearch; const char **dnssearch;
bool ipv4 = true, ipv6 = true;
assert(opts->type == NET_CLIENT_OPTIONS_KIND_USER); assert(opts->type == NET_CLIENT_OPTIONS_KIND_USER);
user = opts->u.user.data; user = opts->u.user.data;
if ((user->has_ipv6 && user->ipv6 && !user->has_ipv4) ||
(user->has_ipv4 && !user->ipv4)) {
ipv4 = 0;
}
if ((user->has_ipv4 && user->ipv4 && !user->has_ipv6) ||
(user->has_ipv6 && !user->ipv6)) {
ipv6 = 0;
}
vnet = user->has_net ? g_strdup(user->net) : vnet = user->has_net ? g_strdup(user->net) :
user->has_ip ? g_strdup_printf("%s/24", user->ip) : user->has_ip ? g_strdup_printf("%s/24", user->ip) :
NULL; NULL;
@ -828,8 +851,9 @@ int net_init_slirp(const NetClientOptions *opts, const char *name,
net_init_slirp_configs(user->hostfwd, SLIRP_CFG_HOSTFWD); net_init_slirp_configs(user->hostfwd, SLIRP_CFG_HOSTFWD);
net_init_slirp_configs(user->guestfwd, 0); net_init_slirp_configs(user->guestfwd, 0);
ret = net_slirp_init(peer, "user", name, user->q_restrict, vnet, ret = net_slirp_init(peer, "user", name, user->q_restrict,
user->host, user->ipv6_prefix, user->ipv6_prefixlen, ipv4, vnet, user->host,
ipv6, user->ipv6_prefix, user->ipv6_prefixlen,
user->ipv6_host, user->hostname, user->tftp, user->ipv6_host, user->hostname, user->tftp,
user->bootfile, user->dhcpstart, user->bootfile, user->dhcpstart,
user->dns, user->ipv6_dns, user->smb, user->dns, user->ipv6_dns, user->smb,

View File

@ -2425,6 +2425,12 @@
# #
# @restrict: #optional isolate the guest from the host # @restrict: #optional isolate the guest from the host
# #
# @ipv4: #optional whether to support IPv4, default true for enabled
# (since 2.6)
#
# @ipv6: #optional whether to support IPv6, default true for enabled
# (since 2.6)
#
# @ip: #optional legacy parameter, use net= instead # @ip: #optional legacy parameter, use net= instead
# #
# @net: #optional IP network address that the guest will see, in the # @net: #optional IP network address that the guest will see, in the
@ -2473,6 +2479,8 @@
'data': { 'data': {
'*hostname': 'str', '*hostname': 'str',
'*restrict': 'bool', '*restrict': 'bool',
'*ipv4': 'bool',
'*ipv6': 'bool',
'*ip': 'str', '*ip': 'str',
'*net': 'str', '*net': 'str',
'*host': 'str', '*host': 'str',

View File

@ -1551,8 +1551,9 @@ DEF("smb", HAS_ARG, QEMU_OPTION_smb, "", QEMU_ARCH_ALL)
DEF("netdev", HAS_ARG, QEMU_OPTION_netdev, DEF("netdev", HAS_ARG, QEMU_OPTION_netdev,
#ifdef CONFIG_SLIRP #ifdef CONFIG_SLIRP
"-netdev user,id=str[,net=addr[/mask]][,host=addr][,ipv6-net=addr[/int]]\n" "-netdev user,id=str[,ipv4[=on|off]][,net=addr[/mask]][,host=addr]\n"
" [,ipv6-host=addr][,restrict=on|off][,hostname=host][,dhcpstart=addr]\n" " [,ipv6[=on|off]][,ipv6-net=addr[/int]][,ipv6-host=addr]\n"
" [,restrict=on|off][,hostname=host][,dhcpstart=addr]\n"
" [,dns=addr][,ipv6-dns=addr][,dnssearch=domain][,tftp=dir]\n" " [,dns=addr][,ipv6-dns=addr][,dnssearch=domain][,tftp=dir]\n"
" [,bootfile=f][,hostfwd=rule][,guestfwd=rule]" " [,bootfile=f][,hostfwd=rule][,guestfwd=rule]"
#ifndef _WIN32 #ifndef _WIN32
@ -1701,6 +1702,9 @@ Connect user mode stack to VLAN @var{n} (@var{n} = 0 is the default).
@itemx name=@var{name} @itemx name=@var{name}
Assign symbolic name for use in monitor commands. Assign symbolic name for use in monitor commands.
@option{ipv4} and @option{ipv6} specify that either IPv4 or IPv6 must
be enabled. If neither is specified both protocols are enabled.
@item net=@var{addr}[/@var{mask}] @item net=@var{addr}[/@var{mask}]
Set IP network address the guest will see. Optionally specify the netmask, Set IP network address the guest will see. Optionally specify the netmask,
either in the form a.b.c.d or as number of valid top-most bits. Default is either in the form a.b.c.d or as number of valid top-most bits. Default is

View File

@ -24,6 +24,10 @@ static void ra_timer_handler(void *opaque)
void icmp6_init(Slirp *slirp) void icmp6_init(Slirp *slirp)
{ {
if (!slirp->in6_enabled) {
return;
}
slirp->ra_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL, ra_timer_handler, slirp); slirp->ra_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL, ra_timer_handler, slirp);
timer_mod(slirp->ra_timer, timer_mod(slirp->ra_timer,
qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + NDP_Interval); qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + NDP_Interval);
@ -31,6 +35,10 @@ void icmp6_init(Slirp *slirp)
void icmp6_cleanup(Slirp *slirp) void icmp6_cleanup(Slirp *slirp)
{ {
if (!slirp->in6_enabled) {
return;
}
timer_del(slirp->ra_timer); timer_del(slirp->ra_timer);
timer_free(slirp->ra_timer); timer_free(slirp->ra_timer);
} }

View File

@ -24,6 +24,11 @@ void ip6_cleanup(Slirp *slirp)
void ip6_input(struct mbuf *m) void ip6_input(struct mbuf *m)
{ {
struct ip6 *ip6; struct ip6 *ip6;
Slirp *slirp = m->slirp;
if (!slirp->in6_enabled) {
goto bad;
}
DEBUG_CALL("ip6_input"); DEBUG_CALL("ip6_input");
DEBUG_ARG("m = %lx", (long)m); DEBUG_ARG("m = %lx", (long)m);

View File

@ -80,6 +80,10 @@ ip_input(struct mbuf *m)
register struct ip *ip; register struct ip *ip;
int hlen; int hlen;
if (!slirp->in_enabled) {
goto bad;
}
DEBUG_CALL("ip_input"); DEBUG_CALL("ip_input");
DEBUG_ARG("m = %p", m); DEBUG_ARG("m = %p", m);
DEBUG_ARG("m_len = %d", m->m_len); DEBUG_ARG("m_len = %d", m->m_len);

View File

@ -8,8 +8,9 @@ typedef struct Slirp Slirp;
int get_dns_addr(struct in_addr *pdns_addr); int get_dns_addr(struct in_addr *pdns_addr);
Slirp *slirp_init(int restricted, struct in_addr vnetwork, Slirp *slirp_init(int restricted, bool in_enabled, struct in_addr vnetwork,
struct in_addr vnetmask, struct in_addr vhost, struct in_addr vnetmask, struct in_addr vhost,
bool in6_enabled,
struct in6_addr vprefix_addr6, uint8_t vprefix_len, struct in6_addr vprefix_addr6, uint8_t vprefix_len,
struct in6_addr vhost6, const char *vhostname, struct in6_addr vhost6, const char *vhostname,
const char *tftp_path, const char *bootfile, const char *tftp_path, const char *bootfile,

View File

@ -200,8 +200,9 @@ static void slirp_init_once(void)
static void slirp_state_save(QEMUFile *f, void *opaque); static void slirp_state_save(QEMUFile *f, void *opaque);
static int slirp_state_load(QEMUFile *f, void *opaque, int version_id); static int slirp_state_load(QEMUFile *f, void *opaque, int version_id);
Slirp *slirp_init(int restricted, struct in_addr vnetwork, Slirp *slirp_init(int restricted, bool in_enabled, struct in_addr vnetwork,
struct in_addr vnetmask, struct in_addr vhost, struct in_addr vnetmask, struct in_addr vhost,
bool in6_enabled,
struct in6_addr vprefix_addr6, uint8_t vprefix_len, struct in6_addr vprefix_addr6, uint8_t vprefix_len,
struct in6_addr vhost6, const char *vhostname, struct in6_addr vhost6, const char *vhostname,
const char *tftp_path, const char *bootfile, const char *tftp_path, const char *bootfile,
@ -216,6 +217,9 @@ Slirp *slirp_init(int restricted, struct in_addr vnetwork,
slirp->grand = g_rand_new(); slirp->grand = g_rand_new();
slirp->restricted = restricted; slirp->restricted = restricted;
slirp->in_enabled = in_enabled;
slirp->in6_enabled = in6_enabled;
if_init(slirp); if_init(slirp);
ip_init(slirp); ip_init(slirp);
ip6_init(slirp); ip6_init(slirp);
@ -694,6 +698,10 @@ static void arp_input(Slirp *slirp, const uint8_t *pkt, int pkt_len)
int ar_op; int ar_op;
struct ex_list *ex_ptr; struct ex_list *ex_ptr;
if (!slirp->in_enabled) {
return;
}
ar_op = ntohs(ah->ar_op); ar_op = ntohs(ah->ar_op);
switch(ar_op) { switch(ar_op) {
case ARPOP_REQUEST: case ARPOP_REQUEST:

View File

@ -180,6 +180,8 @@ struct Slirp {
u_int last_slowtimo; u_int last_slowtimo;
bool do_slowtimo; bool do_slowtimo;
bool in_enabled, in6_enabled;
/* virtual network configuration */ /* virtual network configuration */
struct in_addr vnetwork_addr; struct in_addr vnetwork_addr;
struct in_addr vnetwork_mask; struct in_addr vnetwork_mask;