######################################################################
trace-events-subdirs =
-trace-events-subdirs += util
-trace-events-subdirs += crypto
-trace-events-subdirs += io
-trace-events-subdirs += migration
+trace-events-subdirs += accel/kvm
+trace-events-subdirs += accel/tcg
+trace-events-subdirs += audio
trace-events-subdirs += block
trace-events-subdirs += chardev
+trace-events-subdirs += crypto
+trace-events-subdirs += hw/9pfs
+trace-events-subdirs += hw/acpi
+trace-events-subdirs += hw/alpha
+trace-events-subdirs += hw/arm
+trace-events-subdirs += hw/audio
trace-events-subdirs += hw/block
trace-events-subdirs += hw/block/dataplane
trace-events-subdirs += hw/char
-trace-events-subdirs += hw/intc
-trace-events-subdirs += hw/net
-trace-events-subdirs += hw/rdma
-trace-events-subdirs += hw/rdma/vmw
-trace-events-subdirs += hw/virtio
-trace-events-subdirs += hw/audio
-trace-events-subdirs += hw/misc
-trace-events-subdirs += hw/misc/macio
-trace-events-subdirs += hw/usb
-trace-events-subdirs += hw/scsi
-trace-events-subdirs += hw/nvram
trace-events-subdirs += hw/display
-trace-events-subdirs += hw/input
-trace-events-subdirs += hw/timer
trace-events-subdirs += hw/dma
-trace-events-subdirs += hw/sparc
-trace-events-subdirs += hw/sparc64
-trace-events-subdirs += hw/sd
-trace-events-subdirs += hw/isa
-trace-events-subdirs += hw/mem
+trace-events-subdirs += hw/hppa
trace-events-subdirs += hw/i386
trace-events-subdirs += hw/i386/xen
-trace-events-subdirs += hw/9pfs
-trace-events-subdirs += hw/ppc
+trace-events-subdirs += hw/ide
+trace-events-subdirs += hw/input
+trace-events-subdirs += hw/intc
+trace-events-subdirs += hw/isa
+trace-events-subdirs += hw/mem
+trace-events-subdirs += hw/misc
+trace-events-subdirs += hw/misc/macio
+trace-events-subdirs += hw/net
+trace-events-subdirs += hw/nvram
trace-events-subdirs += hw/pci
trace-events-subdirs += hw/pci-host
+trace-events-subdirs += hw/ppc
+trace-events-subdirs += hw/rdma
+trace-events-subdirs += hw/rdma/vmw
trace-events-subdirs += hw/s390x
+trace-events-subdirs += hw/scsi
+trace-events-subdirs += hw/sd
+trace-events-subdirs += hw/sparc
+trace-events-subdirs += hw/sparc64
+trace-events-subdirs += hw/timer
+trace-events-subdirs += hw/tpm
+trace-events-subdirs += hw/usb
trace-events-subdirs += hw/vfio
-trace-events-subdirs += hw/acpi
-trace-events-subdirs += hw/arm
-trace-events-subdirs += hw/alpha
-trace-events-subdirs += hw/hppa
+trace-events-subdirs += hw/virtio
trace-events-subdirs += hw/xen
-trace-events-subdirs += hw/ide
-trace-events-subdirs += hw/tpm
-trace-events-subdirs += ui
-trace-events-subdirs += audio
+trace-events-subdirs += io
+trace-events-subdirs += linux-user
+trace-events-subdirs += migration
+trace-events-subdirs += nbd
trace-events-subdirs += net
+trace-events-subdirs += qapi
+trace-events-subdirs += qom
+trace-events-subdirs += scsi
trace-events-subdirs += target/arm
trace-events-subdirs += target/i386
trace-events-subdirs += target/mips
-trace-events-subdirs += target/sparc
-trace-events-subdirs += target/s390x
trace-events-subdirs += target/ppc
-trace-events-subdirs += qom
-trace-events-subdirs += linux-user
-trace-events-subdirs += qapi
-trace-events-subdirs += accel/tcg
-trace-events-subdirs += accel/kvm
-trace-events-subdirs += nbd
-trace-events-subdirs += scsi
+trace-events-subdirs += target/s390x
+trace-events-subdirs += target/sparc
+trace-events-subdirs += ui
+trace-events-subdirs += util
trace-events-files = $(SRC_PATH)/trace-events $(trace-events-subdirs:%=$(SRC_PATH)/%/trace-events)
const char *bootfile, const char *vdhcp_start,
const char *vnameserver, const char *vnameserver6,
const char *smb_export, const char *vsmbserver,
- const char **dnssearch, Error **errp)
+ const char **dnssearch, const char *vdomainname,
+ Error **errp)
{
/* default settings according to historic slirp */
struct in_addr net = { .s_addr = htonl(0x0a000200) }; /* 10.0.2.0 */
ip6_dns.s6_addr[15] |= 3;
}
+ if (vdomainname && !*vdomainname) {
+ error_setg(errp, "'domainname' parameter cannot be empty");
+ return -1;
+ }
+
nc = qemu_new_net_client(&net_slirp_info, peer, model, name);
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);
+ dns, ip6_dns, dnssearch, vdomainname, s);
QTAILQ_INSERT_TAIL(&slirp_stacks, s, entry);
for (config = slirp_configs; config; config = config->next) {
goto fail_syntax;
}
- host_port = atoi(p);
+ if (qemu_strtoi(p, NULL, 10, &host_port)) {
+ goto fail_syntax;
+ }
err = slirp_remove_hostfwd(s->slirp, is_udp, host_addr, host_port);
user->ipv6_host, user->hostname, user->tftp,
user->bootfile, user->dhcpstart,
user->dns, user->ipv6_dns, user->smb,
- user->smbserver, dnssearch, errp);
+ user->smbserver, dnssearch, user->domainname, errp);
while (slirp_configs) {
config = slirp_configs;
# @dnssearch: list of DNS suffixes to search, passed as DHCP option
# to the guest
#
+# @domainname: guest-visible domain name of the virtual nameserver
+# (since 2.12)
+#
# @ipv6-prefix: IPv6 network prefix (default is fec0::) (since
# 2.6). The network prefix is given in the usual
# hexadecimal IPv6 address notation.
'*dhcpstart': 'str',
'*dns': 'str',
'*dnssearch': ['String'],
+ '*domainname': 'str',
'*ipv6-prefix': 'str',
'*ipv6-prefixlen': 'int',
'*ipv6-host': 'str',
"-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]"
+ " [,dns=addr][,ipv6-dns=addr][,dnssearch=domain][,domainname=domain]\n"
+ " [,tftp=dir][,bootfile=f][,hostfwd=rule][,guestfwd=rule]"
#ifndef _WIN32
"[,smb=dir[,smbserver=addr]]\n"
#endif
qemu-system-i386 -nic user,dnssearch=mgmt.example.org,dnssearch=example.org
@end example
+@item domainname=@var{domain}
+Specifies the client domain name reported by the built-in DHCP server.
+
@item tftp=@var{dir}
When using the user mode network stack, activate a built-in TFTP
server. The files in @var{dir} will be exposed as the root of a TFTP server.
int i;
DEBUG_CALL("arp_table_add");
- DEBUG_ARG("ip = %s", inet_ntoa(*(struct in_addr *)&ip_addr));
+ DEBUG_ARG("ip = %s", inet_ntoa((struct in_addr){.s_addr = ip_addr}));
DEBUG_ARGS((dfd, " hw addr = %02x:%02x:%02x:%02x:%02x:%02x\n",
ethaddr[0], ethaddr[1], ethaddr[2],
ethaddr[3], ethaddr[4], ethaddr[5]));
int i;
DEBUG_CALL("arp_table_search");
- DEBUG_ARG("ip = %s", inet_ntoa(*(struct in_addr *)&ip_addr));
+ DEBUG_ARG("ip = %s", inet_ntoa((struct in_addr){.s_addr = ip_addr}));
/* If broadcast address */
if (ip_addr == 0xffffffff || ip_addr == broadcast_addr) {
q += val;
}
+ if (slirp->vdomainname) {
+ val = strlen(slirp->vdomainname);
+ *q++ = RFC1533_DOMAINNAME;
+ *q++ = val;
+ memcpy(q, slirp->vdomainname, val);
+ q += val;
+ }
+
if (slirp->vdnssearch) {
size_t spaceleft = sizeof(rbp->bp_vend) - (q - rbp->bp_vend);
val = slirp->vdnssearch_len;
const char *tftp_path, const char *bootfile,
struct in_addr vdhcp_start, struct in_addr vnameserver,
struct in6_addr vnameserver6, const char **vdnssearch,
- void *opaque);
+ const char *vdomainname, void *opaque);
void slirp_cleanup(Slirp *slirp);
void slirp_pollfds_fill(GArray *pollfds, uint32_t *timeout);
/*
* NC-SI (Network Controller Sideband Interface) "echo" model
*
- * Copyright (C) 2016 IBM Corp.
+ * Copyright (C) 2016-2018 IBM Corp.
*
* This code is licensed under the GPL version 2 or later. See the
* COPYING file in the top-level directory.
#include "ncsi-pkt.h"
+static uint32_t ncsi_calculate_checksum(uint16_t *data, int len)
+{
+ uint32_t checksum = 0;
+ int i;
+
+ /*
+ * 32-bit unsigned sum of the NC-SI packet header and NC-SI packet
+ * payload interpreted as a series of 16-bit unsigned integer values.
+ */
+ for (i = 0; i < len; i++) {
+ checksum += htons(data[i]);
+ }
+
+ checksum = (~checksum + 1);
+ return checksum;
+}
+
/* Get Capabilities */
static int ncsi_rsp_handler_gc(struct ncsi_rsp_pkt_hdr *rnh)
{
return 0;
}
+/* Get Parameters */
+static int ncsi_rsp_handler_gp(struct ncsi_rsp_pkt_hdr *rnh)
+{
+ struct ncsi_rsp_gp_pkt *rsp = (struct ncsi_rsp_gp_pkt *) rnh;
+
+ /* no MAC address filters or VLAN filters on the channel */
+ rsp->mac_cnt = 0;
+ rsp->mac_enable = 0;
+ rsp->vlan_cnt = 0;
+ rsp->vlan_enable = 0;
+
+ return 0;
+}
+
static const struct ncsi_rsp_handler {
unsigned char type;
int payload;
{ NCSI_PKT_RSP_EGMF, 4, NULL },
{ NCSI_PKT_RSP_DGMF, 4, NULL },
{ NCSI_PKT_RSP_SNFC, 4, NULL },
- { NCSI_PKT_RSP_GVI, 36, NULL },
+ { NCSI_PKT_RSP_GVI, 40, NULL },
{ NCSI_PKT_RSP_GC, 32, ncsi_rsp_handler_gc },
- { NCSI_PKT_RSP_GP, -1, NULL },
+ { NCSI_PKT_RSP_GP, 40, ncsi_rsp_handler_gp },
{ NCSI_PKT_RSP_GCPS, 172, NULL },
{ NCSI_PKT_RSP_GNS, 172, NULL },
{ NCSI_PKT_RSP_GNPTS, 172, NULL },
(ncsi_reply + ETH_HLEN);
const struct ncsi_rsp_handler *handler = NULL;
int i;
+ int ncsi_rsp_len = sizeof(*nh);
+ uint32_t checksum;
+ uint32_t *pchecksum;
memset(ncsi_reply, 0, sizeof(ncsi_reply));
/* TODO: handle errors */
handler->handler(rnh);
}
+ ncsi_rsp_len += handler->payload;
} else {
rnh->common.length = 0;
rnh->code = htons(NCSI_PKT_RSP_C_UNAVAILABLE);
rnh->reason = htons(NCSI_PKT_RSP_R_UNKNOWN);
}
- /* TODO: add a checksum at the end of the frame but the specs
- * allows it to be zero */
+ /* Add the optional checksum at the end of the frame. */
+ checksum = ncsi_calculate_checksum((uint16_t *) rnh, ncsi_rsp_len);
+ pchecksum = (uint32_t *)((void *) rnh + ncsi_rsp_len);
+ *pchecksum = htonl(checksum);
+ ncsi_rsp_len += 4;
- slirp_output(slirp->opaque, ncsi_reply, ETH_HLEN + sizeof(*nh) +
- (handler ? handler->payload : 0) + 4);
+ slirp_output(slirp->opaque, ncsi_reply, ETH_HLEN + ncsi_rsp_len);
}
const char *tftp_path, const char *bootfile,
struct in_addr vdhcp_start, struct in_addr vnameserver,
struct in6_addr vnameserver6, const char **vdnssearch,
- void *opaque)
+ const char *vdomainname, void *opaque)
{
Slirp *slirp = g_malloc0(sizeof(Slirp));
}
slirp->tftp_prefix = g_strdup(tftp_path);
slirp->bootp_filename = g_strdup(bootfile);
+ slirp->vdomainname = g_strdup(vdomainname);
slirp->vdhcp_startaddr = vdhcp_start;
slirp->vnameserver_addr = vnameserver;
slirp->vnameserver_addr6 = vnameserver6;
g_free(slirp->vdnssearch);
g_free(slirp->tftp_prefix);
g_free(slirp->bootp_filename);
+ g_free(slirp->vdomainname);
g_free(slirp);
}
/* continue; */
} else {
ret = sowrite(so);
+ if (ret > 0) {
+ /* Call tcp_output in case we need to send a window
+ * update to the guest, otherwise it will be stuck
+ * until it sends a window probe. */
+ tcp_output(sototcpcb(so));
+ }
}
- /*
- * XXXXX If we wrote something (a lot), there
- * could be a need for a window update.
- * In the worst case, the remote will send
- * a window probe to get things going again
- */
}
/*
char *bootp_filename;
size_t vdnssearch_len;
uint8_t *vdnssearch;
+ char *vdomainname;
/* tcp states */
struct socket tcb;
memset(&addr, 0, addrlen);
DEBUG_CALL("tcp_listen");
- DEBUG_ARG("haddr = %s", inet_ntoa(*(struct in_addr *)&haddr));
+ DEBUG_ARG("haddr = %s", inet_ntoa((struct in_addr){.s_addr = haddr}));
DEBUG_ARG("hport = %d", ntohs(hport));
- DEBUG_ARG("laddr = %s", inet_ntoa(*(struct in_addr *)&laddr));
+ DEBUG_ARG("laddr = %s", inet_ntoa((struct in_addr){.s_addr = laddr}));
DEBUG_ARG("lport = %d", ntohs(lport));
DEBUG_ARG("flags = %x", flags);
return NULL;
}
qemu_setsockopt(s, SOL_SOCKET, SO_OOBINLINE, &opt, sizeof(int));
+ opt = 1;
+ qemu_setsockopt(s, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(int));
getsockname(s,(struct sockaddr *)&addr,&addrlen);
so->so_ffamily = AF_INET;
socket_set_fast_reuse(s);
opt = 1;
qemu_setsockopt(s, SOL_SOCKET, SO_OOBINLINE, &opt, sizeof(opt));
+ opt = 1;
+ qemu_setsockopt(s, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt));
addr = so->fhost.ss;
DEBUG_CALL(" connect()ing")