[RFC,4/4] virtio-net: implement virtio-net specific announce function

Submitted by Jason Wang on Sept. 27, 2010, 12:51 p.m.

Details

Message ID 20100927125117.12060.55442.stgit@dhcp-91-7.nay.redhat.com.englab.nay.redhat.com
State New
Headers show

Commit Message

Jason Wang Sept. 27, 2010, 12:51 p.m.
This patch tries to announce every mac address for one virtio nic after
migration. The primary mac address is announced unconditionally and other
macaddress are only announced when no vlan is configurated in guest.

For guest with vlan, what we need do is to send tagged gratutious packet, but
current virtio-net implementation can not distinguish the mapping between mac
addresses and vlan. And I believe this function must be implemented with the
modifications of guest drivers ( vlan_dev_info ).

Signed-off-by: Jason Wang <jasowang@redhat.com>
---
 hw/virtio-net.c |   30 ++++++++++++++++++++++++++++++
 1 files changed, 30 insertions(+), 0 deletions(-)

Patch hide | download patch | download mbox

diff --git a/hw/virtio-net.c b/hw/virtio-net.c
index 79afb65..0b47ac2 100644
--- a/hw/virtio-net.c
+++ b/hw/virtio-net.c
@@ -922,6 +922,35 @@  static void virtio_net_cleanup(VLANClientState *nc)
     n->nic = NULL;
 }
 
+static void virtio_net_announce(VLANClientState *nc)
+{
+    uint8_t buf[60];
+    bool has_vlan = false;
+    int len;
+    int i;
+    VirtIONet *n = DO_UPCAST(NICState, nc, nc)->opaque;
+
+    len = announce_self_create(buf, &n->mac[0]);
+    qemu_send_packet_raw(nc, buf, len);
+
+    for (i = 0; i < (MAX_VLAN >> 5); i++) {
+        if (n->vlans[i] & ~0u) {
+            has_vlan = true;
+            break;
+        }
+    }
+
+    if (!has_vlan) {
+	/* It's safe to announce the rest of mac addresses when there's no vlan
+	 * in guest */
+        for (i = 0; i < n->mac_table.in_use; i++) {
+            mac_debug(&n->mac_table.macs[i * ETH_ALEN]);
+            len = announce_self_create(buf, &n->mac_table.macs[i * ETH_ALEN]);
+            qemu_send_packet_raw(nc, buf, len);
+        }
+    }
+}
+
 static NetClientInfo net_virtio_info = {
     .type = NET_CLIENT_TYPE_NIC,
     .size = sizeof(NICState),
@@ -929,6 +958,7 @@  static NetClientInfo net_virtio_info = {
     .receive = virtio_net_receive,
         .cleanup = virtio_net_cleanup,
     .link_status_changed = virtio_net_set_link_status,
+    .announce = virtio_net_announce,
 };
 
 static void virtio_net_set_status(struct VirtIODevice *vdev, uint8_t status)