Skip to contentSkip to conversation

Add qemu_send_raw() to vlan.

PATCH Applied Gleb Natapov 4 participants 13 messages May 26, 2009 – Oct 15, 2009 KVM

lore
Share & tools
lore
#0 lore raw

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
index 8e9178d..3c77b99 100644
@@ -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
index 931133b..3d0b6f2 100644
@@ -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.

#1 lore raw
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
#2 lore raw
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.

#3 lore raw
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_HDR is not upstream.

Mark, how far are we from that?

Signature · 1 line
error compiling committee.c: too many arguments to function
#4 lore raw
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_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.

#5 lore raw
In reply to Gleb Natapov
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.

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.

#6 lore raw
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.

Quoted 9 lines

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.

Signature · 1 line
error compiling committee.c: too many arguments to function
#7 lore raw
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.

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.

Quoted 7 lines
Quoted 4 lines

(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.

--
Gleb.

#8 lore raw
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.

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)

Quoted 6 lines
Quoted 3 lines

Okay. Bug Gleb, please add a signoff.

Thanks, added the signoff and the patch.

Signature · 1 line
error compiling committee.c: too many arguments to function
#9 lore raw
In reply to Gleb Natapov

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
index 931133b..3d0b6f2 100644
...
@@ -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.

#10 lore raw
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
index 931133b..3d0b6f2 100644
...
@@ -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
index 7a363b6..8ea2daf 100644
@@ -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.

#11 lore raw
Quoted 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
index 931133b..3d0b6f2 100644
...
@@ -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:

---
Use qemu_send_packet_raw to send gracious arp. This will ensure that vnet header is handled properly.

savevm.c static void qemu_announce_self_once(void *opaque) · line 135

Quoted 10 lines
savevm.c +1 -1
index 7a363b6..8ea2daf 100644
@@ -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.

#12 lore raw
In reply to Gleb Natapov
Quoted 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
index 931133b..3d0b6f2 100644
...
@@ -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:

---
Use qemu_send_packet_raw to send gracious arp. This will ensure that vnet header is handled properly.

Applied, thanks.