Add qemu_send_raw() to vlan.
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.
hw/virtio-net.c +19 -4
@@ -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);
net.c +49 -0
67 lines not on this page · raw message
net.h +2 -0
@@ -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,
--
Gleb.
Quoted 3 lines · Gleb Natapov
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?
Signature · 1 line
error compiling committee.c: too many arguments to function
Quoted 7 lines · Avi Kivity
Quoted 3 lines · Gleb Natapov
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.
Quoted 4 lines · Gleb Natapov
Quoted 2 lines · Avi Kivity
Gleb Natapov wrote:
Quoted 10 lines
Quoted 7 lines
Quoted 4 lines
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_HDRis not upstream.
Mark, how far are we from that?
Signature · 1 line
error compiling committee.c: too many arguments to function
Quoted 9 lines · Avi Kivity
Quoted 8 lines · Gleb Natapov
Quoted 6 lines · Avi Kivity
Quoted 4 lines · Gleb Natapov
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.
Quoted 8 lines
Quoted 6 lines
Quoted 3 lines
This is for
announce_self(), no? If so, upstream has the same problems?
VNET_HDRis 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.
Mark McLoughlin
Acked-byQuoted 2 lines · Gleb Natapov
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 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.
Quoted 8 lines · Mark McLoughlin
Quoted 3 lines · Gleb Natapov
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 <[email protected]>
Quoted 9 lines
This isn't ideal, but neither is the current
VNET_HDRstuff 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 mergingVNET_HDRsupport upstream.(Gleb - it might be worth patching qemu.git to use
qemu_send_packet()inannounce_self(), that will reduce the delta between the trees)
Okay. Bug Gleb, please add a signoff.
Signature · 1 line
error compiling committee.c: too many arguments to function
Quoted 14 lines · Avi Kivity
Quoted 13 lines · Mark McLoughlin
Quoted 3 lines · Gleb Natapov
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 <[email protected]>This isn't ideal, but neither is the current
VNET_HDRstuff 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 mergingVNET_HDRsupport upstream.
Quoted 7 lines
Quoted 4 lines
(Gleb - it might be worth patching qemu.git to use
qemu_send_packet()inannounce_self(), that will reduce the delta between the trees)Okay. Bug Gleb, please add a signoff.
--
Gleb.
Quoted 23 lines · Gleb Natapov
Quoted 21 lines · Avi Kivity
Quoted 19 lines · Mark McLoughlin
Quoted 4 lines · Gleb Natapov
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 <[email protected]>This isn't ideal, but neither is the current
VNET_HDRstuff 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 mergingVNET_HDRsupport upstream.(Gleb - it might be worth patching qemu.git to use
qemu_send_packet()inannounce_self(), that will reduce the delta between the trees)
Quoted 6 lines
Quoted 3 lines
Okay. Bug Gleb, please add a signoff.
Signed-off-by Gleb Natapov <[email protected]>
Thanks, added the signoff and the patch.
Signature · 1 line
error compiling committee.c: too many arguments to function
Hi Gleb,
Quoted 2 lines · Gleb Natapov
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.
...
net.h int qemu_can_send_packet(VLANClientState *vc); · line 70
Quoted 13 lines
net.h +1
-0@@ -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,
I've only just now noticed that we never actually made announce_self() use this ... care to do that?
Cheers,
Mark.
Quoted 6 lines · Mark McLoughlin
Hi Gleb,
Quoted 2 lines · Gleb Natapov
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.
...
Quoted 17 lines
net.h int qemu_can_send_packet(VLANClientState *vc); · line 70
Quoted 13 lines
net.h +1
-0@@ -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,I've only just now noticed that we never actually made
announce_self()use this ... care to do that?
Something like this:
---
Use qemu_send_packet_raw to send gracious arp. This will ensure that vnet header is handled properly.
savevm.c +1 -1
@@ -132,7 +132,7 @@ static void qemu_announce_self_once(void *opaque) len =announce_self_create (buf, nd_table[i].macaddr); vlan = nd_table[i].vlan;for (vc = vlan->first_client; vc !=NULL ; vc = vc->next) { - vc->receive (vc, buf, len); +qemu_send_packet_raw (vc, buf, len); } }if (count--) {
--
Gleb.
Mark McLoughlin
Acked-byQuoted 24 lines · Gleb Natapov
Quoted 6 lines · Mark McLoughlin
Hi Gleb,
Quoted 2 lines · Gleb Natapov
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.
...
Quoted 17 lines
net.h int qemu_can_send_packet(VLANClientState *vc); · line 70
Quoted 13 lines
net.h +1
-0@@ -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,I've only just now noticed that we never actually made
announce_self()use this ... care to do that?
Quoted 7 lines
Something like this:
---
Useqemu_send_packet_rawto send gracious arp. This will ensure that vnet header is handled properly.Signed-off-by Gleb Natapov <[email protected]>
savevm.c static void qemu_announce_self_once(void *opaque) · line 135
Quoted 10 lines
savevm.c +1
-1@@ -132,7 +132,7 @@ static void qemu_announce_self_once(void *opaque) len =announce_self_create (buf, nd_table[i].macaddr); vlan = nd_table[i].vlan;for (vc = vlan->first_client; vc !=NULL ; vc = vc->next) { - vc->receive (vc, buf, len); +qemu_send_packet_raw (vc, buf, len);
This makes things even more gratuitous because we're making every net client send the packet rather than receive it, but it works fine in practice.
Cheers,
Mark.
Marcelo Tosatti
AppliedQuoted 24 lines · Gleb Natapov
Quoted 6 lines · Mark McLoughlin
Hi Gleb,
Quoted 2 lines · Gleb Natapov
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.
...
Quoted 17 lines
net.h int qemu_can_send_packet(VLANClientState *vc); · line 70
Quoted 13 lines
net.h +1
-0@@ -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,I've only just now noticed that we never actually made
announce_self()use this ... care to do that?
Quoted 5 lines
Something like this:
---
Useqemu_send_packet_rawto send gracious arp. This will ensure that vnet header is handled properly.
Applied, thanks.