Message ID | 20090526100302.GS3948@redhat.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Gleb Natapov wrote: > It gets packet without virtio header and adds it if needed. Allows to > inject packets to vlan from outside. To send gracious arp for instance. > This is for announce_self(), no? If so, upstream has the same problems?
On Tue, May 26, 2009 at 01:05:35PM +0300, Avi Kivity wrote: > Gleb Natapov wrote: >> It gets packet without virtio header and adds it if needed. Allows to >> inject packets to vlan from outside. To send gracious arp for instance. >> > > This is for announce_self(), no? If so, upstream has the same problems? > VNET_HDR is not upstream. -- Gleb. -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Gleb Natapov wrote: > On Tue, May 26, 2009 at 01:05:35PM +0300, Avi Kivity wrote: > >> Gleb Natapov wrote: >> >>> It gets packet without virtio header and adds it if needed. Allows to >>> inject packets to vlan from outside. To send gracious arp for instance. >>> >>> >> This is for announce_self(), no? If so, upstream has the same problems? >> >> > VNET_HDR is not upstream. > > Mark, how far are we from that?
On Tue, 2009-05-26 at 13:11 +0300, Avi Kivity wrote: > Gleb Natapov wrote: > > On Tue, May 26, 2009 at 01:05:35PM +0300, Avi Kivity wrote: > > > >> Gleb Natapov wrote: > >> > >>> It gets packet without virtio header and adds it if needed. Allows to > >>> inject packets to vlan from outside. To send gracious arp for instance. > >>> > >>> > >> This is for announce_self(), no? If so, upstream has the same problems? > >> > >> > > VNET_HDR is not upstream. > > > > > > Mark, how far are we from that? We first need to add support for paired devices (i.e. a tap/virtio-net pair) rather than trying to munge this stuff into the VLAN code. Cheers, Mark. -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Tue, 2009-05-26 at 13:03 +0300, Gleb Natapov wrote: > It gets packet without virtio header and adds it if needed. Allows to > inject packets to vlan from outside. To send gracious arp for instance. Acked-by: Mark McLoughlin <markmc@redhat.com> This isn't ideal, but neither is the current VNET_HDR stuff and it does fix a genuine bug. At least it's not changing existing APIs and makes it clear this is a problem we also need to solve when merging VNET_HDR support upstream. (Gleb - it might be worth patching qemu.git to use qemu_send_packet() in announce_self(), that will reduce the delta between the trees) Cheers, Mark. -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Mark McLoughlin wrote: > On Tue, 2009-05-26 at 13:03 +0300, Gleb Natapov wrote: > >> It gets packet without virtio header and adds it if needed. Allows to >> inject packets to vlan from outside. To send gracious arp for instance. >> > > Acked-by: Mark McLoughlin <markmc@redhat.com> > > This isn't ideal, but neither is the current VNET_HDR stuff and it does > fix a genuine bug. At least it's not changing existing APIs and makes it > clear this is a problem we also need to solve when merging VNET_HDR > support upstream. > > (Gleb - it might be worth patching qemu.git to use qemu_send_packet() in > announce_self(), that will reduce the delta between the trees) > > Okay. Bug Gleb, please add a signoff.
On Tue, May 26, 2009 at 02:15:37PM +0300, Avi Kivity wrote: > Mark McLoughlin wrote: >> On Tue, 2009-05-26 at 13:03 +0300, Gleb Natapov wrote: >> >>> It gets packet without virtio header and adds it if needed. Allows to >>> inject packets to vlan from outside. To send gracious arp for instance. >>> >> >> Acked-by: Mark McLoughlin <markmc@redhat.com> >> >> This isn't ideal, but neither is the current VNET_HDR stuff and it does >> fix a genuine bug. At least it's not changing existing APIs and makes it >> clear this is a problem we also need to solve when merging VNET_HDR >> support upstream. >> >> (Gleb - it might be worth patching qemu.git to use qemu_send_packet() in >> announce_self(), that will reduce the delta between the trees) >> >> > > Okay. Bug Gleb, please add a signoff. > Signed-off-by: Gleb Natapov <gleb@redhat.com> -- Gleb. -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Gleb Natapov wrote: > On Tue, May 26, 2009 at 02:15:37PM +0300, Avi Kivity wrote: > >> Mark McLoughlin wrote: >> >>> On Tue, 2009-05-26 at 13:03 +0300, Gleb Natapov wrote: >>> >>> >>>> It gets packet without virtio header and adds it if needed. Allows to >>>> inject packets to vlan from outside. To send gracious arp for instance. >>>> >>>> >>> Acked-by: Mark McLoughlin <markmc@redhat.com> >>> >>> This isn't ideal, but neither is the current VNET_HDR stuff and it does >>> fix a genuine bug. At least it's not changing existing APIs and makes it >>> clear this is a problem we also need to solve when merging VNET_HDR >>> support upstream. >>> >>> (Gleb - it might be worth patching qemu.git to use qemu_send_packet() in >>> announce_self(), that will reduce the delta between the trees) >>> >>> >>> >> Okay. Bug Gleb, please add a signoff. >> >> > Signed-off-by: Gleb Natapov <gleb@redhat.com> > > Thanks, added the signoff and the patch.
diff --git a/hw/virtio-net.c b/hw/virtio-net.c index 8e9178d..3c77b99 100644 --- a/hw/virtio-net.c +++ b/hw/virtio-net.c @@ -389,7 +389,7 @@ static int iov_fill(struct iovec *iov, int iovcnt, const void *buf, int count) } static int receive_header(VirtIONet *n, struct iovec *iov, int iovcnt, - const void *buf, size_t size, size_t hdr_len) + const void *buf, size_t size, size_t hdr_len, int raw) { struct virtio_net_hdr *hdr = (struct virtio_net_hdr *)iov[0].iov_base; int offset = 0; @@ -399,7 +399,11 @@ static int receive_header(VirtIONet *n, struct iovec *iov, int iovcnt, #ifdef TAP_VNET_HDR if (tap_has_vnet_hdr(n->vc->vlan->first_client)) { - memcpy(hdr, buf, sizeof(*hdr)); + if (!raw) { + memcpy(hdr, buf, sizeof(*hdr)); + } else { + memset(hdr, 0, sizeof(*hdr)); + } offset = sizeof(*hdr); work_around_broken_dhclient(hdr, buf + offset, size - offset); } @@ -452,7 +456,7 @@ static int receive_filter(VirtIONet *n, const uint8_t *buf, int size) return 0; } -static void virtio_net_receive(void *opaque, const uint8_t *buf, int size) +static void virtio_net_receive2(void *opaque, const uint8_t *buf, int size, int raw) { VirtIONet *n = opaque; struct virtio_net_hdr_mrg_rxbuf *mhdr = NULL; @@ -502,7 +506,7 @@ static void virtio_net_receive(void *opaque, const uint8_t *buf, int size) mhdr = (struct virtio_net_hdr_mrg_rxbuf *)sg[0].iov_base; offset += receive_header(n, sg, elem.in_num, - buf + offset, size - offset, hdr_len); + buf + offset, size - offset, hdr_len, raw); total += hdr_len; } @@ -524,6 +528,16 @@ static void virtio_net_receive(void *opaque, const uint8_t *buf, int size) virtio_notify(&n->vdev, n->rx_vq); } +static void virtio_net_receive(void *opaque, const uint8_t *buf, int size) +{ + virtio_net_receive2(opaque, buf, size, 0); +} + +static void virtio_net_receive_raw(void *opaque, const uint8_t *buf, int size) +{ + virtio_net_receive2(opaque, buf, size, 1); +} + /* TX */ static void virtio_net_flush_tx(VirtIONet *n, VirtQueue *vq) { @@ -721,6 +735,7 @@ VirtIODevice *virtio_net_init(DeviceState *dev) virtio_net_can_receive, virtio_net_cleanup, n); n->vc->link_status_changed = virtio_net_set_link_status; + n->vc->fd_read_raw = virtio_net_receive_raw; qemu_format_nic_info_str(n->vc, n->mac); diff --git a/net.c b/net.c index 3dfc728..01e31db 100644 --- a/net.c +++ b/net.c @@ -456,6 +456,31 @@ int qemu_send_packet(VLANClientState *vc, const uint8_t *buf, int size) return ret; } +void qemu_send_packet_raw(VLANClientState *sender, const uint8_t *buf, int size) +{ + VLANState *vlan = sender->vlan; + VLANClientState *vc; + + if (sender->link_down) + return; + +#ifdef DEBUG_NET + printf("vlan %d send raw:\n", vlan->id); + hex_dump(stdout, buf, size); +#endif + for(vc = vlan->first_client; vc != NULL; vc = vc->next) { + if (vc == sender || vc->link_down) { + continue; + } + if (vc->fd_read_raw) { + vc->fd_read_raw(vc->opaque, buf, size); + } else { + vc->fd_read(vc->opaque, buf, size); + } + } + return; +} + static ssize_t vc_sendv_compat(VLANClientState *vc, const struct iovec *iov, int iovcnt) { @@ -823,6 +848,29 @@ static void tap_receive(void *opaque, const uint8_t *buf, int size) tap_receive_iov(opaque, iov, i); } +static void tap_receive_raw(void *opaque, const uint8_t *buf, int size) +{ + struct iovec iov[2]; + int i = 0; + +#ifdef IFF_VNET_HDR + TAPState *s = opaque; + struct virtio_net_hdr hdr = { 0, }; + + if (s->has_vnet_hdr && s->using_vnet_hdr) { + iov[i].iov_base = &hdr; + iov[i].iov_len = sizeof(hdr); + i++; + } +#endif + + iov[i].iov_base = (char *) buf; + iov[i].iov_len = size; + i++; + + tap_receive_iov(opaque, iov, i); +} + static int tap_can_send(void *opaque) { TAPState *s = opaque; @@ -992,6 +1040,7 @@ static TAPState *net_tap_fd_init(VLANState *vlan, s->vc = qemu_new_vlan_client(vlan, model, name, tap_receive, NULL, tap_cleanup, s); s->vc->fd_readv = tap_receive_iov; + s->vc->fd_read_raw = tap_receive_raw; #ifdef TUNSETOFFLOAD s->vc->set_offload = tap_set_offload; tap_set_offload(s->vc, 0, 0, 0, 0); diff --git a/net.h b/net.h index 931133b..3d0b6f2 100644 --- a/net.h +++ b/net.h @@ -15,6 +15,7 @@ typedef void (SetOffload)(VLANClientState *, int, int, int, int); struct VLANClientState { IOReadHandler *fd_read; + IOReadHandler *fd_read_raw; IOReadvHandler *fd_readv; /* Packets may still be sent if this returns zero. It's used to rate-limit the slirp code. */ @@ -63,6 +64,7 @@ int qemu_can_send_packet(VLANClientState *vc); ssize_t qemu_sendv_packet(VLANClientState *vc, const struct iovec *iov, int iovcnt); int qemu_send_packet(VLANClientState *vc, const uint8_t *buf, int size); +void qemu_send_packet_raw(VLANClientState *vc, const uint8_t *buf, int size); void qemu_format_nic_info_str(VLANClientState *vc, uint8_t macaddr[6]); void qemu_check_nic_model(NICInfo *nd, const char *model); void qemu_check_nic_model_list(NICInfo *nd, const char * const *models,