1 From 8a59df2477f869eb4b3f582c36cb0e08018fbcff Mon Sep 17 00:00:00 2001
2 From: Dan McDonald <danmcd@omniti.com>
3 Date: Wed, 22 Apr 2015 16:15:39 -0400
4 Subject: [PATCH] Revert "HVM-798 qemu could know about vnd"
6 This reverts commit 31a39c6ea8dfc9021436264d83dc07a4d799ff61.
9 net/vnic.c | 246 ++++++++++++++++++++++---------------------------------------
10 2 files changed, 88 insertions(+), 160 deletions(-)
14 diff -ruN illumos-kvm-cmd-41e7c3e192eb39bb5ced7667fdc12ad2b33e646d.orig/build.sh illumos-kvm-cmd-41e7c3e192eb39bb5ced7667fdc12ad2b33e646d.patched/build.sh
15 --- illumos-kvm-cmd-41e7c3e192eb39bb5ced7667fdc12ad2b33e646d.orig/build.sh 2020-03-19 21:53:41.308240253 +0000
16 +++ illumos-kvm-cmd-41e7c3e192eb39bb5ced7667fdc12ad2b33e646d.patched/build.sh 2020-03-19 21:55:18.480389342 +0000
18 XCFLAGS="$XCFLAGS -fno-builtin -I${PNGINC} -isystem ${DESTDIR}/usr/include -msave-args"
19 XLDFLAGS="-nodefaultlibs -L${PNGLIB} -L${DESTDIR}/usr/lib/amd64 -L${DESTDIR}/lib/amd64"
20 XLDFLAGS="${XLDFLAGS} -Wl,-zfatal-warnings -Wl,-zassert-deflib"
21 -XLDFLAGS="${XLDFLAGS} -lz -lm -lc -lvnd"
22 +XLDFLAGS="${XLDFLAGS} -lz -lm -lc"
25 --extra-cflags="${XCFLAGS}" \
26 diff -ruN illumos-kvm-cmd-41e7c3e192eb39bb5ced7667fdc12ad2b33e646d.orig/net/vnic.c illumos-kvm-cmd-41e7c3e192eb39bb5ced7667fdc12ad2b33e646d.patched/net/vnic.c
27 --- illumos-kvm-cmd-41e7c3e192eb39bb5ced7667fdc12ad2b33e646d.orig/net/vnic.c 2020-03-19 21:53:41.379418566 +0000
28 +++ illumos-kvm-cmd-41e7c3e192eb39bb5ced7667fdc12ad2b33e646d.patched/net/vnic.c 2020-03-19 22:30:09.207208336 +0000
31 * QEMU System Emulator
32 - * illumos VNIC/vnd support
33 + * Solaris VNIC support
35 * Copyright 2016 Joyent, Inc.
40 #include <netpacket/packet.h>
42 #include <net/if_dl.h>
43 #include <sys/ethernet.h>
44 +#include <sys/dlpi.h>
45 #include <sys/types.h>
50 -#include <sys/frameio.h>
53 #include "net/vnic-dhcp.h"
55 uint8_t vns_buf[VNIC_BUFSIZE];
56 uint8_t vns_txbuf[VNIC_BUFSIZE];
58 - vnd_handle_t *vns_hdl;
59 + dlpi_handle_t vns_hdl;
61 - frameio_t *vns_rfio;
62 - frameio_t *vns_wfio;
65 static void vnic_update_fd_handler(VNICState *);
67 vnic_write_poll(vsp, 1);
71 - * Because this is a single packet API, just read(2). If QEMU's net backend were
72 - * better we could send more packets at once.
75 vnic_read_packet(VNICState *vsp, uint8_t *buf, int len)
83 + sbuf.buf = (char *)buf;
86 - ret = read(vsp->vns_fd, buf, len);
87 + ret = getmsg(vsp->vns_fd, NULL, &sbuf, &flags);
88 } while (ret == -1 && errno == EINTR);
90 if (ret == -1 && errno == EAGAIN) {
91 - vnic_read_poll(vsp, 1);
92 + vnic_write_poll(vsp, 1);
105 - * For a single packet, just use write(2).
108 vnic_write_packet(VNICState *vsp, const uint8_t *buf, int len)
111 + struct strbuf sbuf;
116 + sbuf.buf = (char *)buf;
119 - ret = write(vsp->vns_fd, buf, len);
120 + ret = putmsg(vsp->vns_fd, NULL, &sbuf, flags);
121 } while (ret == -1 && errno == EINTR);
123 if (ret == -1 && errno == EAGAIN) {
138 VNICState *vsp = DO_UPCAST(VNICState, vns_nc, ncp);
141 + debug_eth_frame(buf, size);
144 if (vsp->vns_ds.vnds_enabled && get_ethertype(buf, size, ðtype)) {
145 VNICDHCPState *vdsp = &vsp->vns_ds;
147 @@ -220,117 +229,6 @@
148 return (vnic_write_packet(vsp, buf, size));
152 -vnic_receive_iov(VLANClientState *ncp, const struct iovec *iov,
157 - size_t total, altsize;
158 - VNICState *vsp = DO_UPCAST(VNICState, vns_nc, ncp);
160 - for (total = 0, i = 0; i < iovcnt; i++) {
161 - total += (iov + i)->iov_len;
164 - if (vsp->vns_ds.vnds_enabled && get_ethertypev(iov, iovcnt, ðtype)) {
166 - * Basically drop the packet because we can't send a
167 - * reply at this time. It's unfortunate, but we don't
168 - * really have the proper infrastructure to do something
169 - * else with this at this time.
171 - if (!vnic_can_send(vsp))
174 - VNICDHCPState *vdsp = &vsp->vns_ds;
178 - if (!is_arp_requestv(iov, iovcnt, vdsp))
180 - ret = create_arp_responsev(iov, iovcnt, vdsp);
183 - if (!is_dhcp_requestv(iov, iovcnt))
185 - ret = create_dhcp_responsev(iov, iovcnt, vdsp);
191 - /* This failed, drop it and continue */
195 - ret = qemu_send_packet_async(&vsp->vns_nc,
196 - vdsp->vnds_buf, ret, vnic_send_completed);
198 - * qemu has told us that it can't receive any more data
199 - * at this time for the guest (host->guest traffic) so
200 - * turn off our read poll until we get that the send has
204 - vnic_read_poll(vsp, 0);
210 - * Copy the iovcs to our write frameio. Be on the lookout for someone
211 - * giving us more vectors than we support in frameio. In that case,
212 - * let's go ahead and just simply concat the rest.
214 - for (i = 0; i < MIN(iovcnt, FRAMEIO_NVECS_MAX - 1); i++, iov++) {
215 - vsp->vns_wfio->fio_vecs[i].fv_buf = iov->iov_base;
216 - vsp->vns_wfio->fio_vecs[i].fv_buflen = iov->iov_len;
220 - for (i = MIN(iovcnt, FRAMEIO_NVECS_MAX - 1); i != iovcnt; i++, iov++) {
222 - * The packet is too large. We're goin to silently drop it...
224 - if (altsize + iov->iov_len > VNIC_BUFSIZE)
227 - bcopy(iov->iov_base, vsp->vns_txbuf + altsize, iov->iov_len);
228 - altsize += iov->iov_len;
230 - if (altsize != 0) {
231 - vsp->vns_wfio->fio_vecs[FRAMEIO_NVECS_MAX-1].fv_buf =
233 - vsp->vns_wfio->fio_vecs[FRAMEIO_NVECS_MAX-1].fv_buflen =
237 - vsp->vns_wfio->fio_nvecs = MIN(iovcnt, FRAMEIO_NVECS_MAX);
238 - vsp->vns_wfio->fio_nvpf = MIN(iovcnt, FRAMEIO_NVECS_MAX);
240 - ret = vnd_frameio_write(vsp->vns_hdl, vsp->vns_wfio);
241 - } while (ret == -1 && errno == EINTR);
243 - if (ret == -1 && errno == EAGAIN) {
244 - vnic_write_poll(vsp, 1);
246 - } else if (ret == -1) {
251 - for (i = 0; i < vsp->vns_wfio->fio_nvecs; i++) {
252 - if (vsp->vns_wfio->fio_vecs[i].fv_actlen == 0 &&
253 - vsp->vns_wfio->fio_vecs[i].fv_buflen == 0)
256 - total += vsp->vns_wfio->fio_vecs[i].fv_actlen;
263 vnic_cleanup(VLANClientState *ncp)
267 qemu_purge_queued_packets(ncp);
269 - vnd_close(vsp->vns_hdl);
270 + dlpi_close(vsp->vns_hdl);
274 @@ -357,41 +255,42 @@
275 .type = NET_CLIENT_TYPE_VNIC,
276 .size = sizeof (VNICState),
277 .receive = vnic_receive,
278 - .receive_iov = vnic_receive_iov,
280 .cleanup = vnic_cleanup
284 - * Set up all the known values for our frame I/O devices.
286 +#ifdef CONFIG_SUNOS_VNIC_KVM
288 -vnic_frameio_init(VNICState *vsp)
289 +net_init_kvm(int vfd)
291 - vsp->vns_rfio = qemu_mallocz(sizeof (frameio_t) +
292 - sizeof (framevec_t) * FRAMEIO_NVECS_MAX);
293 - if (vsp->vns_rfio == NULL)
295 - vsp->vns_wfio = qemu_mallocz(sizeof (frameio_t) +
296 - sizeof (framevec_t) * FRAMEIO_NVECS_MAX);
297 - if (vsp->vns_wfio == NULL)
299 - vsp->vns_rfio->fio_version = FRAMEIO_CURRENT_VERSION;
300 - vsp->vns_rfio->fio_nvpf = 1;
301 - vsp->vns_wfio->fio_version = FRAMEIO_CURRENT_VERSION;
302 - vsp->vns_wfio->fio_nvpf = 1;
305 + if ((kfd = open("/dev/kvm", O_RDWR)) < 0) {
306 + error_report("can't open /dev/kvm for vnic: %s\n",
311 + /* XXX We shouldn't be embedding the KVM_NET_QUEUE fd */
312 + if (ioctl(kfd, 0x2000ae21, vfd) < 0) {
313 + error_report("can't ioctl: %s\n", strerror(errno));
324 net_init_vnic(QemuOpts *opts, Monitor *mon, const char *name, VLANState *vlan)
326 - int fd, len, vnderr, syserr;
328 const char *ifname, *mac;
330 VLANClientState *ncp;
332 - vnd_prop_buf_t vib;
334 if ((ifname = qemu_opt_get(opts, "ifname")) == NULL) {
335 error_report("missing ifname required for vnic\n");
336 @@ -411,36 +310,48 @@
337 ncp = qemu_new_net_client(&net_vnic_info, vlan, NULL, "vnic", name);
338 vsp = DO_UPCAST(VNICState, vns_nc, ncp);
340 + if (dlpi_open(ifname, &vsp->vns_hdl, DLPI_RAW) != DLPI_SUCCESS) {
341 + error_report("vnic: failed to open interface %s", ifname);
345 - vsp->vns_hdl = vnd_open(NULL, ifname, &vnderr, &syserr);
346 - if (vsp->vns_hdl == NULL) {
347 - const char *err = vnderr != VND_E_SYS ?
348 - vnd_strerror(vnderr) : vnd_strsyserror(syserr);
349 - error_report("vnic: failed to open interface %s - %s\n",
351 + if (dlpi_bind(vsp->vns_hdl, DLPI_ANY_SAP, &vsp->vns_sap) != DLPI_SUCCESS) {
352 + error_report("vnic: failed to bind interface %s", ifname);
356 - vib.vpb_size = 1024 * 1024 * 4; /* 4 MB */
357 - if (vnd_prop_set(vsp->vns_hdl, VND_PROP_RXBUF, &vib,
358 - sizeof (vib)) != 0) {
359 - const char *err = vnderr != VND_E_SYS ?
360 - vnd_strerror(vnderr) : vnd_strsyserror(syserr);
361 - error_report("failed to change rx buf size: %s\n", err);
363 + * We only set the mac address of the vnic if the user passed in the
364 + * option on the command line.
367 + if (dlpi_set_physaddr(vsp->vns_hdl, DL_CURR_PHYS_ADDR, macaddr,
368 + ETHERADDRL) != DLPI_SUCCESS) {
369 + error_report("vnic: failed to set mac address\n");
375 + * We are enabling support for two different kinds of promiscuous modes.
376 + * The first is getting us the basics of the unicast traffic that we
377 + * care about. The latter is going to ensure that we also get other
378 + * types of physical traffic such as multicast and broadcast.
380 + if (dlpi_promiscon(vsp->vns_hdl, DL_PROMISC_SAP) != DLPI_SUCCESS) {
381 + error_report("vnic: failed to be promiscous with interface %s",
386 - vib.vpb_size = 1024 * 1024 * 4; /* 4 MB */
387 - if (vnd_prop_set(vsp->vns_hdl, VND_PROP_TXBUF, &vib,
388 - sizeof (vib)) != 0) {
389 - const char *err = vnderr != VND_E_SYS ?
390 - vnd_strerror(vnderr) : vnd_strsyserror(syserr);
391 - error_report("failed to change tx buf size: %s\n", err);
392 + if (dlpi_promiscon(vsp->vns_hdl, DL_PROMISC_PHYS) != DLPI_SUCCESS) {
393 + error_report("vnic: failed to be promiscous with interface %s",
398 + fd = dlpi_fd(vsp->vns_hdl);
400 - fd = vnd_pollfd(vsp->vns_hdl);
401 if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) {
402 error_report("vnic: failed to set fd on interface %s to "
403 "non-blocking: %s\n", ifname, strerror(errno));
405 if (vnic_dhcp_init(&vsp->vns_ds, opts) == 0)
408 - if (vnic_frameio_init(vsp) != 0) {
409 - error_report("vnic: failed initialize frameio: %s\n",
413 +#ifdef CONFIG_SUNOS_VNIC_KVM
417 /* We have to manually intialize the polling for read */
418 vnic_read_poll(vsp, 1);