slirp: Allow disabling IPv4 or IPv6
Add ipv4 and ipv6 boolean options, so the user can setup IPv4-only and IPv6-only network environments. Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org> Reviewed-by: Thomas Huth <thuth@redhat.com>
This commit is contained in:
parent
de1d099a44
commit
0b11c03662
36
net/slirp.c
36
net/slirp.c
@ -136,8 +136,8 @@ static NetClientInfo net_slirp_info = {
|
||||
|
||||
static int net_slirp_init(NetClientState *peer, const char *model,
|
||||
const char *name, int restricted,
|
||||
const char *vnetwork, const char *vhost,
|
||||
const char *vprefix6, int vprefix6_len,
|
||||
bool ipv4, const char *vnetwork, const char *vhost,
|
||||
bool ipv6, const char *vprefix6, int vprefix6_len,
|
||||
const char *vhost6,
|
||||
const char *vhostname, const char *tftp_export,
|
||||
const char *bootfile, const char *vdhcp_start,
|
||||
@ -165,6 +165,19 @@ static int net_slirp_init(NetClientState *peer, const char *model,
|
||||
char *end;
|
||||
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) {
|
||||
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->slirp = slirp_init(restricted, net, mask, host,
|
||||
ip6_prefix, vprefix6_len, ip6_host,
|
||||
s->slirp = slirp_init(restricted, ipv4, net, mask, host,
|
||||
ipv6, ip6_prefix, vprefix6_len, ip6_host,
|
||||
vhostname, tftp_export, bootfile, dhcp,
|
||||
dns, ip6_dns, dnssearch, s);
|
||||
QTAILQ_INSERT_TAIL(&slirp_stacks, s, entry);
|
||||
@ -813,10 +826,20 @@ int net_init_slirp(const NetClientOptions *opts, const char *name,
|
||||
int ret;
|
||||
const NetdevUserOptions *user;
|
||||
const char **dnssearch;
|
||||
bool ipv4 = true, ipv6 = true;
|
||||
|
||||
assert(opts->type == NET_CLIENT_OPTIONS_KIND_USER);
|
||||
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) :
|
||||
user->has_ip ? g_strdup_printf("%s/24", user->ip) :
|
||||
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->guestfwd, 0);
|
||||
|
||||
ret = net_slirp_init(peer, "user", name, user->q_restrict, vnet,
|
||||
user->host, user->ipv6_prefix, user->ipv6_prefixlen,
|
||||
ret = net_slirp_init(peer, "user", name, user->q_restrict,
|
||||
ipv4, vnet, user->host,
|
||||
ipv6, user->ipv6_prefix, user->ipv6_prefixlen,
|
||||
user->ipv6_host, user->hostname, user->tftp,
|
||||
user->bootfile, user->dhcpstart,
|
||||
user->dns, user->ipv6_dns, user->smb,
|
||||
|
@ -2425,6 +2425,12 @@
|
||||
#
|
||||
# @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
|
||||
#
|
||||
# @net: #optional IP network address that the guest will see, in the
|
||||
@ -2473,6 +2479,8 @@
|
||||
'data': {
|
||||
'*hostname': 'str',
|
||||
'*restrict': 'bool',
|
||||
'*ipv4': 'bool',
|
||||
'*ipv6': 'bool',
|
||||
'*ip': 'str',
|
||||
'*net': 'str',
|
||||
'*host': 'str',
|
||||
|
@ -1551,8 +1551,9 @@ DEF("smb", HAS_ARG, QEMU_OPTION_smb, "", QEMU_ARCH_ALL)
|
||||
|
||||
DEF("netdev", HAS_ARG, QEMU_OPTION_netdev,
|
||||
#ifdef CONFIG_SLIRP
|
||||
"-netdev user,id=str[,net=addr[/mask]][,host=addr][,ipv6-net=addr[/int]]\n"
|
||||
" [,ipv6-host=addr][,restrict=on|off][,hostname=host][,dhcpstart=addr]\n"
|
||||
"-netdev user,id=str[,ipv4[=on|off]][,net=addr[/mask]][,host=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"
|
||||
" [,bootfile=f][,hostfwd=rule][,guestfwd=rule]"
|
||||
#ifndef _WIN32
|
||||
@ -1701,6 +1702,9 @@ Connect user mode stack to VLAN @var{n} (@var{n} = 0 is the default).
|
||||
@itemx name=@var{name}
|
||||
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}]
|
||||
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
|
||||
|
@ -24,6 +24,10 @@ static void ra_timer_handler(void *opaque)
|
||||
|
||||
void icmp6_init(Slirp *slirp)
|
||||
{
|
||||
if (!slirp->in6_enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
slirp->ra_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL, ra_timer_handler, slirp);
|
||||
timer_mod(slirp->ra_timer,
|
||||
qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + NDP_Interval);
|
||||
@ -31,6 +35,10 @@ void icmp6_init(Slirp *slirp)
|
||||
|
||||
void icmp6_cleanup(Slirp *slirp)
|
||||
{
|
||||
if (!slirp->in6_enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
timer_del(slirp->ra_timer);
|
||||
timer_free(slirp->ra_timer);
|
||||
}
|
||||
|
@ -24,6 +24,11 @@ void ip6_cleanup(Slirp *slirp)
|
||||
void ip6_input(struct mbuf *m)
|
||||
{
|
||||
struct ip6 *ip6;
|
||||
Slirp *slirp = m->slirp;
|
||||
|
||||
if (!slirp->in6_enabled) {
|
||||
goto bad;
|
||||
}
|
||||
|
||||
DEBUG_CALL("ip6_input");
|
||||
DEBUG_ARG("m = %lx", (long)m);
|
||||
|
@ -80,6 +80,10 @@ ip_input(struct mbuf *m)
|
||||
register struct ip *ip;
|
||||
int hlen;
|
||||
|
||||
if (!slirp->in_enabled) {
|
||||
goto bad;
|
||||
}
|
||||
|
||||
DEBUG_CALL("ip_input");
|
||||
DEBUG_ARG("m = %p", m);
|
||||
DEBUG_ARG("m_len = %d", m->m_len);
|
||||
|
@ -8,8 +8,9 @@ typedef struct Slirp Slirp;
|
||||
|
||||
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,
|
||||
bool in6_enabled,
|
||||
struct in6_addr vprefix_addr6, uint8_t vprefix_len,
|
||||
struct in6_addr vhost6, const char *vhostname,
|
||||
const char *tftp_path, const char *bootfile,
|
||||
|
@ -200,8 +200,9 @@ static void slirp_init_once(void)
|
||||
static void slirp_state_save(QEMUFile *f, void *opaque);
|
||||
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,
|
||||
bool in6_enabled,
|
||||
struct in6_addr vprefix_addr6, uint8_t vprefix_len,
|
||||
struct in6_addr vhost6, const char *vhostname,
|
||||
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->restricted = restricted;
|
||||
|
||||
slirp->in_enabled = in_enabled;
|
||||
slirp->in6_enabled = in6_enabled;
|
||||
|
||||
if_init(slirp);
|
||||
ip_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;
|
||||
struct ex_list *ex_ptr;
|
||||
|
||||
if (!slirp->in_enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
ar_op = ntohs(ah->ar_op);
|
||||
switch(ar_op) {
|
||||
case ARPOP_REQUEST:
|
||||
|
@ -180,6 +180,8 @@ struct Slirp {
|
||||
u_int last_slowtimo;
|
||||
bool do_slowtimo;
|
||||
|
||||
bool in_enabled, in6_enabled;
|
||||
|
||||
/* virtual network configuration */
|
||||
struct in_addr vnetwork_addr;
|
||||
struct in_addr vnetwork_mask;
|
||||
|
Loading…
Reference in New Issue
Block a user