From: Alex Williamson <alex.williamson@hp.com> To: anthony@codemonkey.ws, qemu-devel@nongnu.org Cc: markmc@redhat.com, kvm@vger.kernel.org, alex.williamson@hp.com Subject: [PATCH v3 5/8] qemu:virtio-net: Add promiscuous and all-multicast mode bits Date: Wed, 04 Feb 2009 17:18:16 -0700 [thread overview] Message-ID: <20090205001816.27879.71002.stgit@kvm.aw> (raw) In-Reply-To: <20090205001707.27879.22745.stgit@kvm.aw> Add a new RX_MODE control virtqueue class with commands PROMISC and ALLMULTI and usage documented in virtio-net.h allowing the guest to manipulate packet receiving options. We don't export a feature for this until we also add the MAC filter table. Note, for compatibility with older guest drivers we need to default to promiscuous. Signed-off-by: Alex Williamson <alex.williamson@hp.com> --- hw/virtio-net.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++- hw/virtio-net.h | 11 +++++++++++ 2 files changed, 58 insertions(+), 1 deletions(-) diff --git a/hw/virtio-net.c b/hw/virtio-net.c index 5a8287b..7e130f7 100644 --- a/hw/virtio-net.c +++ b/hw/virtio-net.c @@ -16,7 +16,7 @@ #include "qemu-timer.h" #include "virtio-net.h" -#define VIRTIO_NET_VM_VERSION 3 +#define VIRTIO_NET_VM_VERSION 4 typedef struct VirtIONet { @@ -30,6 +30,8 @@ typedef struct VirtIONet QEMUTimer *tx_timer; int tx_timer_active; int mergeable_rx_bufs; + int promisc; + int allmulti; } VirtIONet; /* TODO @@ -78,6 +80,15 @@ static void virtio_net_set_link_status(VLANClientState *vc) virtio_notify_config(&n->vdev); } +static void virtio_net_reset(VirtIODevice *vdev) +{ + VirtIONet *n = to_virtio_net(vdev); + + /* Reset back to compatibility mode */ + n->promisc = 1; + n->allmulti = 0; +} + static uint32_t virtio_net_get_features(VirtIODevice *vdev) { uint32_t features = (1 << VIRTIO_NET_F_MAC) | @@ -94,8 +105,31 @@ static void virtio_net_set_features(VirtIODevice *vdev, uint32_t features) n->mergeable_rx_bufs = !!(features & (1 << VIRTIO_NET_F_MRG_RXBUF)); } +static int virtio_net_handle_rx_mode(VirtIONet *n, uint8_t cmd, + VirtQueueElement *elem) +{ + uint8_t on; + + if (elem->out_num != 2 || elem->out_sg[1].iov_len != sizeof(on)) { + fprintf(stderr, "virtio-net ctrl invalid rx mode command\n"); + exit(1); + } + + on = ldub_p(elem->out_sg[1].iov_base); + + if (cmd == VIRTIO_NET_CTRL_RX_MODE_PROMISC) + n->promisc = on; + else if (cmd == VIRTIO_NET_CTRL_RX_MODE_ALLMULTI) + n->allmulti = on; + else + return VIRTIO_NET_ERR; + + return VIRTIO_NET_OK; +} + static void virtio_net_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq) { + VirtIONet *n = to_virtio_net(vdev); struct virtio_net_ctrl_hdr ctrl; virtio_net_ctrl_ack status = VIRTIO_NET_ERR; VirtQueueElement elem; @@ -115,6 +149,9 @@ static void virtio_net_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq) ctrl.class = ldub_p(elem.out_sg[0].iov_base); ctrl.cmd = ldub_p(elem.out_sg[0].iov_base + sizeof(ctrl.class)); + if (ctrl.class == VIRTIO_NET_CTRL_RX_MODE) + status = virtio_net_handle_rx_mode(n, ctrl.cmd, &elem); + stb_p(elem.in_sg[elem.in_num - 1].iov_base, status); virtqueue_push(vq, &elem, sizeof(status)); @@ -339,6 +376,8 @@ static void virtio_net_save(QEMUFile *f, void *opaque) qemu_put_be32(f, n->tx_timer_active); qemu_put_be32(f, n->mergeable_rx_bufs); qemu_put_be16(f, n->status); + qemu_put_be32(f, n->promisc); + qemu_put_be32(f, n->allmulti); } static int virtio_net_load(QEMUFile *f, void *opaque, int version_id) @@ -357,6 +396,11 @@ static int virtio_net_load(QEMUFile *f, void *opaque, int version_id) if (version_id >= 3) n->status = qemu_get_be16(f); + if (version_id >= 4) { + n->promisc = qemu_get_be32(f); + n->allmulti = qemu_get_be32(f); + } + if (n->tx_timer_active) { qemu_mod_timer(n->tx_timer, qemu_get_clock(vm_clock) + TX_TIMER_INTERVAL); @@ -385,6 +429,7 @@ void virtio_net_init(PCIBus *bus, NICInfo *nd, int devfn) n->vdev.set_config = virtio_net_set_config; n->vdev.get_features = virtio_net_get_features; n->vdev.set_features = virtio_net_set_features; + n->vdev.reset = virtio_net_reset; n->rx_vq = virtio_add_queue(&n->vdev, 256, virtio_net_handle_rx); n->tx_vq = virtio_add_queue(&n->vdev, 256, virtio_net_handle_tx); n->ctrl_vq = virtio_add_queue(&n->vdev, 16, virtio_net_handle_ctrl); @@ -399,6 +444,7 @@ void virtio_net_init(PCIBus *bus, NICInfo *nd, int devfn) n->tx_timer = qemu_new_timer(vm_clock, virtio_net_tx_timer, n); n->tx_timer_active = 0; n->mergeable_rx_bufs = 0; + n->promisc = 1; /* for compatibility */ register_savevm("virtio-net", virtio_net_id++, VIRTIO_NET_VM_VERSION, virtio_net_save, virtio_net_load, n); diff --git a/hw/virtio-net.h b/hw/virtio-net.h index 119e38d..ce8e4b4 100644 --- a/hw/virtio-net.h +++ b/hw/virtio-net.h @@ -41,6 +41,7 @@ #define VIRTIO_NET_F_MRG_RXBUF 15 /* Host can merge receive buffers. */ #define VIRTIO_NET_F_STATUS 16 /* virtio_net_config.status available */ #define VIRTIO_NET_F_CTRL_VQ 17 /* Control channel available */ +#define VIRTIO_NET_F_CTRL_RX 18 /* Control channel RX mode support */ #define VIRTIO_NET_S_LINK_UP 1 /* Link is up */ @@ -102,4 +103,14 @@ typedef uint8_t virtio_net_ctrl_ack; #define VIRTIO_NET_OK 0 #define VIRTIO_NET_ERR 1 +/* + * Control the RX mode, ie. promisucous and allmulti. PROMISC and + * ALLMULTI commands require an "out" sg entry containing a 1 byte + * state value, zero = disable, non-zero = enable. These commands + * are supported with the VIRTIO_NET_F_CTRL_RX feature. + */ +#define VIRTIO_NET_CTRL_RX_MODE 0 + #define VIRTIO_NET_CTRL_RX_MODE_PROMISC 0 + #define VIRTIO_NET_CTRL_RX_MODE_ALLMULTI 1 + #endif
WARNING: multiple messages have this Message-ID (diff)
From: Alex Williamson <alex.williamson@hp.com> To: anthony@codemonkey.ws, qemu-devel@nongnu.org Cc: markmc@redhat.com, alex.williamson@hp.com, kvm@vger.kernel.org Subject: [Qemu-devel] [PATCH v3 5/8] qemu:virtio-net: Add promiscuous and all-multicast mode bits Date: Wed, 04 Feb 2009 17:18:16 -0700 [thread overview] Message-ID: <20090205001816.27879.71002.stgit@kvm.aw> (raw) In-Reply-To: <20090205001707.27879.22745.stgit@kvm.aw> Add a new RX_MODE control virtqueue class with commands PROMISC and ALLMULTI and usage documented in virtio-net.h allowing the guest to manipulate packet receiving options. We don't export a feature for this until we also add the MAC filter table. Note, for compatibility with older guest drivers we need to default to promiscuous. Signed-off-by: Alex Williamson <alex.williamson@hp.com> --- hw/virtio-net.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++- hw/virtio-net.h | 11 +++++++++++ 2 files changed, 58 insertions(+), 1 deletions(-) diff --git a/hw/virtio-net.c b/hw/virtio-net.c index 5a8287b..7e130f7 100644 --- a/hw/virtio-net.c +++ b/hw/virtio-net.c @@ -16,7 +16,7 @@ #include "qemu-timer.h" #include "virtio-net.h" -#define VIRTIO_NET_VM_VERSION 3 +#define VIRTIO_NET_VM_VERSION 4 typedef struct VirtIONet { @@ -30,6 +30,8 @@ typedef struct VirtIONet QEMUTimer *tx_timer; int tx_timer_active; int mergeable_rx_bufs; + int promisc; + int allmulti; } VirtIONet; /* TODO @@ -78,6 +80,15 @@ static void virtio_net_set_link_status(VLANClientState *vc) virtio_notify_config(&n->vdev); } +static void virtio_net_reset(VirtIODevice *vdev) +{ + VirtIONet *n = to_virtio_net(vdev); + + /* Reset back to compatibility mode */ + n->promisc = 1; + n->allmulti = 0; +} + static uint32_t virtio_net_get_features(VirtIODevice *vdev) { uint32_t features = (1 << VIRTIO_NET_F_MAC) | @@ -94,8 +105,31 @@ static void virtio_net_set_features(VirtIODevice *vdev, uint32_t features) n->mergeable_rx_bufs = !!(features & (1 << VIRTIO_NET_F_MRG_RXBUF)); } +static int virtio_net_handle_rx_mode(VirtIONet *n, uint8_t cmd, + VirtQueueElement *elem) +{ + uint8_t on; + + if (elem->out_num != 2 || elem->out_sg[1].iov_len != sizeof(on)) { + fprintf(stderr, "virtio-net ctrl invalid rx mode command\n"); + exit(1); + } + + on = ldub_p(elem->out_sg[1].iov_base); + + if (cmd == VIRTIO_NET_CTRL_RX_MODE_PROMISC) + n->promisc = on; + else if (cmd == VIRTIO_NET_CTRL_RX_MODE_ALLMULTI) + n->allmulti = on; + else + return VIRTIO_NET_ERR; + + return VIRTIO_NET_OK; +} + static void virtio_net_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq) { + VirtIONet *n = to_virtio_net(vdev); struct virtio_net_ctrl_hdr ctrl; virtio_net_ctrl_ack status = VIRTIO_NET_ERR; VirtQueueElement elem; @@ -115,6 +149,9 @@ static void virtio_net_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq) ctrl.class = ldub_p(elem.out_sg[0].iov_base); ctrl.cmd = ldub_p(elem.out_sg[0].iov_base + sizeof(ctrl.class)); + if (ctrl.class == VIRTIO_NET_CTRL_RX_MODE) + status = virtio_net_handle_rx_mode(n, ctrl.cmd, &elem); + stb_p(elem.in_sg[elem.in_num - 1].iov_base, status); virtqueue_push(vq, &elem, sizeof(status)); @@ -339,6 +376,8 @@ static void virtio_net_save(QEMUFile *f, void *opaque) qemu_put_be32(f, n->tx_timer_active); qemu_put_be32(f, n->mergeable_rx_bufs); qemu_put_be16(f, n->status); + qemu_put_be32(f, n->promisc); + qemu_put_be32(f, n->allmulti); } static int virtio_net_load(QEMUFile *f, void *opaque, int version_id) @@ -357,6 +396,11 @@ static int virtio_net_load(QEMUFile *f, void *opaque, int version_id) if (version_id >= 3) n->status = qemu_get_be16(f); + if (version_id >= 4) { + n->promisc = qemu_get_be32(f); + n->allmulti = qemu_get_be32(f); + } + if (n->tx_timer_active) { qemu_mod_timer(n->tx_timer, qemu_get_clock(vm_clock) + TX_TIMER_INTERVAL); @@ -385,6 +429,7 @@ void virtio_net_init(PCIBus *bus, NICInfo *nd, int devfn) n->vdev.set_config = virtio_net_set_config; n->vdev.get_features = virtio_net_get_features; n->vdev.set_features = virtio_net_set_features; + n->vdev.reset = virtio_net_reset; n->rx_vq = virtio_add_queue(&n->vdev, 256, virtio_net_handle_rx); n->tx_vq = virtio_add_queue(&n->vdev, 256, virtio_net_handle_tx); n->ctrl_vq = virtio_add_queue(&n->vdev, 16, virtio_net_handle_ctrl); @@ -399,6 +444,7 @@ void virtio_net_init(PCIBus *bus, NICInfo *nd, int devfn) n->tx_timer = qemu_new_timer(vm_clock, virtio_net_tx_timer, n); n->tx_timer_active = 0; n->mergeable_rx_bufs = 0; + n->promisc = 1; /* for compatibility */ register_savevm("virtio-net", virtio_net_id++, VIRTIO_NET_VM_VERSION, virtio_net_save, virtio_net_load, n); diff --git a/hw/virtio-net.h b/hw/virtio-net.h index 119e38d..ce8e4b4 100644 --- a/hw/virtio-net.h +++ b/hw/virtio-net.h @@ -41,6 +41,7 @@ #define VIRTIO_NET_F_MRG_RXBUF 15 /* Host can merge receive buffers. */ #define VIRTIO_NET_F_STATUS 16 /* virtio_net_config.status available */ #define VIRTIO_NET_F_CTRL_VQ 17 /* Control channel available */ +#define VIRTIO_NET_F_CTRL_RX 18 /* Control channel RX mode support */ #define VIRTIO_NET_S_LINK_UP 1 /* Link is up */ @@ -102,4 +103,14 @@ typedef uint8_t virtio_net_ctrl_ack; #define VIRTIO_NET_OK 0 #define VIRTIO_NET_ERR 1 +/* + * Control the RX mode, ie. promisucous and allmulti. PROMISC and + * ALLMULTI commands require an "out" sg entry containing a 1 byte + * state value, zero = disable, non-zero = enable. These commands + * are supported with the VIRTIO_NET_F_CTRL_RX feature. + */ +#define VIRTIO_NET_CTRL_RX_MODE 0 + #define VIRTIO_NET_CTRL_RX_MODE_PROMISC 0 + #define VIRTIO_NET_CTRL_RX_MODE_ALLMULTI 1 + #endif
next prev parent reply other threads:[~2009-02-05 0:21 UTC|newest] Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top 2009-02-05 0:17 [PATCH v3 0/8] qemu:virtio-net: Add MAC and VLAN filtering Alex Williamson 2009-02-05 0:17 ` [Qemu-devel] " Alex Williamson 2009-02-05 0:17 ` [PATCH v3 1/8] qemu:virtio-net: Save status and add some save infrastructure Alex Williamson 2009-02-05 0:17 ` [Qemu-devel] " Alex Williamson 2009-02-05 22:36 ` Anthony Liguori 2009-02-05 22:36 ` [Qemu-devel] " Anthony Liguori 2009-02-05 0:18 ` [PATCH v3 2/8] qemu:virtio-net: Allow setting the MAC address via set_config Alex Williamson 2009-02-05 0:18 ` [Qemu-devel] " Alex Williamson 2009-02-05 0:18 ` [PATCH v3 3/8] qemu:virtio-net: Define ETH_ALEN for use when manipulating MAC addresses Alex Williamson 2009-02-05 0:18 ` [Qemu-devel] " Alex Williamson 2009-02-05 0:18 ` [PATCH v3 4/8] qemu:virtio-net: Add a virtqueue for control commands from the guest Alex Williamson 2009-02-05 0:18 ` [Qemu-devel] " Alex Williamson 2009-02-05 0:18 ` Alex Williamson [this message] 2009-02-05 0:18 ` [Qemu-devel] [PATCH v3 5/8] qemu:virtio-net: Add promiscuous and all-multicast mode bits Alex Williamson 2009-02-05 0:18 ` [PATCH v3 6/8] qemu:virtio-net: Enable filtering based on MAC, promisc, broadcast and allmulti Alex Williamson 2009-02-05 0:18 ` [Qemu-devel] " Alex Williamson 2009-02-05 0:18 ` [PATCH v3 7/8] qemu:virtio-net: Add additional MACs via a filter table Alex Williamson 2009-02-05 0:18 ` [Qemu-devel] " Alex Williamson 2009-02-05 0:18 ` [PATCH v3 8/8] qemu:virtio-net: Add VLAN filtering Alex Williamson 2009-02-05 0:18 ` [Qemu-devel] " Alex Williamson
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20090205001816.27879.71002.stgit@kvm.aw \ --to=alex.williamson@hp.com \ --cc=anthony@codemonkey.ws \ --cc=kvm@vger.kernel.org \ --cc=markmc@redhat.com \ --cc=qemu-devel@nongnu.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.