netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC v3 PATCH 0/4] Send gratuitous packets by guest
@ 2011-10-27  8:48 Jason Wang
  2011-10-27  8:48 ` [RFC v3 PATCH 1/4] announce self after vm start Jason Wang
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Jason Wang @ 2011-10-27  8:48 UTC (permalink / raw)
  To: aliguori, mst, jan.kiszka, rusty, qemu-devel, blauwirbel, stefanha
  Cc: netdev, kvm

We only track primary mac address in qemu and send rarp packets after
migration to notify the switch to update its mac address table. This
may not works when guest have complicated network configurations such
as tagged vlan or ipv6, those connections may be lost or stalled after
migration.

One method to handle them is snooping the network traffic in qemu and
recording use of mac, but this method would hurt performance and is
impossible for network backend such as vhost.

So the best method to address it is to let guest instead of qemu to
send gratuitous packet. This series first add a model specific
fucntion which can let nic model to implement its own announce
method and then implement a virtio-net specific function to
let guest send the gratitous packet.

Changes from v2:

- Conditionally send the notification interrupt to guest (only for
migration, cont, loadvm).
- Remove the unused patch of function export.
- Typos and other comments from Stefan Hajnoczi.
- Disable guest announce for compat machine types.

---

Jason Wang (4):
      announce self after vm start
      net: model specific announcing support
      virtio-net: notify guest to annouce itself
      virtio-net: compat guest announce support.


 gdbstub.c       |    2 +-
 hw/pc_piix.c    |   16 ++++++++++++++++
 hw/virtio-net.c |   18 +++++++++++++++++-
 hw/virtio-net.h |    3 +++
 migration.c     |    4 ++--
 monitor.c       |    4 ++--
 net.h           |    2 ++
 savevm.c        |   10 ++++++----
 sysemu.h        |    2 +-
 vl.c            |    7 +++++--
 10 files changed, 55 insertions(+), 13 deletions(-)

-- 
Jason Wang

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [RFC v3 PATCH 1/4] announce self after vm start
  2011-10-27  8:48 [RFC v3 PATCH 0/4] Send gratuitous packets by guest Jason Wang
@ 2011-10-27  8:48 ` Jason Wang
  2011-10-27  8:48 ` [RFC v3 PATCH 2/4] net: model specific announcing support Jason Wang
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Jason Wang @ 2011-10-27  8:48 UTC (permalink / raw)
  To: aliguori, mst, jan.kiszka, rusty, qemu-devel, blauwirbel, stefanha
  Cc: netdev, kvm

This patch moves qemu_announce_self() to vm_start() and add a new
parameters to control whether sending gratuitous packet is needed.

This is bacause the following reasons:

- Gratuitous packet is also needed when we resume a stopped vm or
  successfuly load a state.
- The ability of sending gratuitous packet by guest may change the
  state of device, so we need to do it after vm is started.

Signed-off-by: Jason Wang <jasowang@redhat.com>
---
 gdbstub.c   |    2 +-
 migration.c |    4 ++--
 monitor.c   |    4 ++--
 savevm.c    |    2 +-
 sysemu.h    |    2 +-
 vl.c        |    7 +++++--
 6 files changed, 12 insertions(+), 9 deletions(-)

diff --git a/gdbstub.c b/gdbstub.c
index 4009058..5f6238e 100644
--- a/gdbstub.c
+++ b/gdbstub.c
@@ -371,7 +371,7 @@ static inline void gdb_continue(GDBState *s)
 #ifdef CONFIG_USER_ONLY
     s->running_state = 1;
 #else
-    vm_start();
+    vm_start(false);
 #endif
 }
 
diff --git a/migration.c b/migration.c
index bdca72e..8580fa7 100644
--- a/migration.c
+++ b/migration.c
@@ -90,7 +90,7 @@ void process_incoming_migration(QEMUFile *f)
     DPRINTF("successfully loaded vm state\n");
 
     if (autostart) {
-        vm_start();
+        vm_start(true);
     } else {
         runstate_set(RUN_STATE_PRELAUNCH);
     }
@@ -308,7 +308,7 @@ static void migrate_fd_put_ready(void *opaque)
         }
         if (s->state != MIG_STATE_COMPLETED) {
             if (old_vm_running) {
-                vm_start();
+                vm_start(false);
             }
         }
     }
diff --git a/monitor.c b/monitor.c
index ffda0fe..633e2de 100644
--- a/monitor.c
+++ b/monitor.c
@@ -1252,7 +1252,7 @@ static int do_cont(Monitor *mon, const QDict *qdict, QObject **ret_data)
     bdrv_iterate(encrypted_bdrv_it, &context);
     /* only resume the vm if all keys are set and valid */
     if (!context.err) {
-        vm_start();
+        vm_start(true);
         return 0;
     } else {
         return -1;
@@ -2710,7 +2710,7 @@ static void do_loadvm(Monitor *mon, const QDict *qdict)
     vm_stop(RUN_STATE_RESTORE_VM);
 
     if (load_vmstate(name) == 0 && saved_vm_running) {
-        vm_start();
+        vm_start(true);
     }
 }
 
diff --git a/savevm.c b/savevm.c
index f01838f..73ee6e2 100644
--- a/savevm.c
+++ b/savevm.c
@@ -2077,7 +2077,7 @@ void do_savevm(Monitor *mon, const QDict *qdict)
 
  the_end:
     if (saved_vm_running)
-        vm_start();
+        vm_start(false);
 }
 
 int load_vmstate(const char *name)
diff --git a/sysemu.h b/sysemu.h
index 22cd720..686f1ec 100644
--- a/sysemu.h
+++ b/sysemu.h
@@ -34,7 +34,7 @@ void vm_state_notify(int running, RunState state);
 #define VMRESET_SILENT   false
 #define VMRESET_REPORT   true
 
-void vm_start(void);
+void vm_start(bool announce);
 void vm_stop(RunState state);
 void vm_stop_force_state(RunState state);
 
diff --git a/vl.c b/vl.c
index 1ddb17b..e216966 100644
--- a/vl.c
+++ b/vl.c
@@ -1253,7 +1253,7 @@ void vm_state_notify(int running, RunState state)
     }
 }
 
-void vm_start(void)
+void vm_start(bool announce)
 {
     if (!runstate_is_running()) {
         cpu_enable_ticks();
@@ -1261,6 +1261,9 @@ void vm_start(void)
         vm_state_notify(1, RUN_STATE_RUNNING);
         resume_all_vcpus();
         monitor_protocol_event(QEVENT_RESUME, NULL);
+        if (announce) {
+            qemu_announce_self();
+        }
     }
 }
 
@@ -3440,7 +3443,7 @@ int main(int argc, char **argv, char **envp)
             exit(ret);
         }
     } else if (autostart) {
-        vm_start();
+        vm_start(false);
     }
 
     os_setup_post();

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [RFC v3 PATCH 2/4] net: model specific announcing support
  2011-10-27  8:48 [RFC v3 PATCH 0/4] Send gratuitous packets by guest Jason Wang
  2011-10-27  8:48 ` [RFC v3 PATCH 1/4] announce self after vm start Jason Wang
@ 2011-10-27  8:48 ` Jason Wang
  2011-10-27  8:48 ` [RFC v3 PATCH 3/4] virtio-net: notify guest to annouce itself Jason Wang
  2011-10-27  8:49 ` [RFC v3 PATCH 4/4] virtio-net: compat guest announce support Jason Wang
  3 siblings, 0 replies; 5+ messages in thread
From: Jason Wang @ 2011-10-27  8:48 UTC (permalink / raw)
  To: aliguori, mst, jan.kiszka, rusty, qemu-devel, blauwirbel, stefanha
  Cc: netdev, kvm

This patch introduces a function pointer in NetClientInfo which is
called during self announcement to do the model specific announcing.

The first user would be virtio-net.

Signed-off-by: Jason Wang <jasowang@redhat.com>
---
 net.h    |    2 ++
 savevm.c |    8 +++++---
 2 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/net.h b/net.h
index 9f633f8..7654769 100644
--- a/net.h
+++ b/net.h
@@ -46,6 +46,7 @@ typedef ssize_t (NetReceive)(VLANClientState *, const uint8_t *, size_t);
 typedef ssize_t (NetReceiveIOV)(VLANClientState *, const struct iovec *, int);
 typedef void (NetCleanup) (VLANClientState *);
 typedef void (LinkStatusChanged)(VLANClientState *);
+typedef int (NetAnnounce)(VLANClientState *);
 
 typedef struct NetClientInfo {
     net_client_type type;
@@ -57,6 +58,7 @@ typedef struct NetClientInfo {
     NetCleanup *cleanup;
     LinkStatusChanged *link_status_changed;
     NetPoll *poll;
+    NetAnnounce *announce;
 } NetClientInfo;
 
 struct VLANClientState {
diff --git a/savevm.c b/savevm.c
index 73ee6e2..46389b2 100644
--- a/savevm.c
+++ b/savevm.c
@@ -122,10 +122,12 @@ static void qemu_announce_self_iter(NICState *nic, void *opaque)
 {
     uint8_t buf[60];
     int len;
+    NetAnnounce *func = nic->nc.info->announce;
 
-    len = announce_self_create(buf, nic->conf->macaddr.a);
-
-    qemu_send_packet_raw(&nic->nc, buf, len);
+    if (func == NULL || func(&nic->nc) != 0) {
+        len = announce_self_create(buf, nic->conf->macaddr.a);
+        qemu_send_packet_raw(&nic->nc, buf, len);
+    }
 }
 
 

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [RFC v3 PATCH 3/4] virtio-net: notify guest to annouce itself
  2011-10-27  8:48 [RFC v3 PATCH 0/4] Send gratuitous packets by guest Jason Wang
  2011-10-27  8:48 ` [RFC v3 PATCH 1/4] announce self after vm start Jason Wang
  2011-10-27  8:48 ` [RFC v3 PATCH 2/4] net: model specific announcing support Jason Wang
@ 2011-10-27  8:48 ` Jason Wang
  2011-10-27  8:49 ` [RFC v3 PATCH 4/4] virtio-net: compat guest announce support Jason Wang
  3 siblings, 0 replies; 5+ messages in thread
From: Jason Wang @ 2011-10-27  8:48 UTC (permalink / raw)
  To: aliguori, mst, jan.kiszka, rusty, qemu-devel, blauwirbel, stefanha
  Cc: netdev, kvm

It's hard to track all mac address and its usage (vlan, bondings,
ipv6) in qemu to send proper gratituous packet. The better choice is
let guest to do it.

The patch introduces a new rw config status bit of virtio-net,
VIRTIO_NET_S_ANNOUNCE which is used to notify guest to announce
presence of its link through config update interrupt. When gust have
done the annoucement, it should clear that bit.

The feature is negotiated by bit VIRTIO_NET_F_ANNOUNCE.

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

diff --git a/hw/virtio-net.c b/hw/virtio-net.c
index 8c2f460..5451eec 100644
--- a/hw/virtio-net.c
+++ b/hw/virtio-net.c
@@ -95,6 +95,8 @@ static void virtio_net_set_config(VirtIODevice *vdev, const uint8_t *config)
         memcpy(n->mac, netcfg.mac, ETH_ALEN);
         qemu_format_nic_info_str(&n->nic->nc, n->mac);
     }
+
+    memcpy(&n->status, &netcfg.status, sizeof(n->status));
 }
 
 static bool virtio_net_started(VirtIONet *n, uint8_t status)
@@ -227,7 +229,7 @@ static uint32_t virtio_net_get_features(VirtIODevice *vdev, uint32_t features)
 {
     VirtIONet *n = to_virtio_net(vdev);
 
-    features |= (1 << VIRTIO_NET_F_MAC);
+    features |= (1 << VIRTIO_NET_F_MAC | 1 << VIRTIO_NET_F_GUEST_ANNOUNCE);
 
     if (peer_has_vnet_hdr(n)) {
         tap_using_vnet_hdr(n->nic->nc.peer, 1);
@@ -983,6 +985,19 @@ static void virtio_net_cleanup(VLANClientState *nc)
     n->nic = NULL;
 }
 
+static int virtio_net_announce(VLANClientState *nc)
+{
+    VirtIONet *n = DO_UPCAST(NICState, nc, nc)->opaque;
+
+    if (n->vdev.guest_features & (0x1 << VIRTIO_NET_F_GUEST_ANNOUNCE)) {
+        n->status |= VIRTIO_NET_S_ANNOUNCE;
+        virtio_notify_config(&n->vdev);
+        return 0;
+    }
+
+    return 1;
+}
+
 static NetClientInfo net_virtio_info = {
     .type = NET_CLIENT_TYPE_NIC,
     .size = sizeof(NICState),
@@ -990,6 +1005,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,
 };
 
 VirtIODevice *virtio_net_init(DeviceState *dev, NICConf *conf,
diff --git a/hw/virtio-net.h b/hw/virtio-net.h
index 4468741..9f8cea7 100644
--- a/hw/virtio-net.h
+++ b/hw/virtio-net.h
@@ -44,8 +44,10 @@
 #define VIRTIO_NET_F_CTRL_RX    18      /* Control channel RX mode support */
 #define VIRTIO_NET_F_CTRL_VLAN  19      /* Control channel VLAN filtering */
 #define VIRTIO_NET_F_CTRL_RX_EXTRA 20   /* Extra RX mode control support */
+#define VIRTIO_NET_F_GUEST_ANNOUNCE 21  /* Guest can announce itself */
 
 #define VIRTIO_NET_S_LINK_UP    1       /* Link is up */
+#define VIRTIO_NET_S_ANNOUNCE   2       /* Announcement is needed */
 
 #define TX_TIMER_INTERVAL 150000 /* 150 us */
 
@@ -176,6 +178,7 @@ struct virtio_net_ctrl_mac {
         DEFINE_PROP_BIT("guest_tso6", _state, _field, VIRTIO_NET_F_GUEST_TSO6, true), \
         DEFINE_PROP_BIT("guest_ecn", _state, _field, VIRTIO_NET_F_GUEST_ECN, true), \
         DEFINE_PROP_BIT("guest_ufo", _state, _field, VIRTIO_NET_F_GUEST_UFO, true), \
+        DEFINE_PROP_BIT("guest_announce", _state, _field, VIRTIO_NET_F_GUEST_ANNOUNCE, true), \
         DEFINE_PROP_BIT("host_tso4", _state, _field, VIRTIO_NET_F_HOST_TSO4, true), \
         DEFINE_PROP_BIT("host_tso6", _state, _field, VIRTIO_NET_F_HOST_TSO6, true), \
         DEFINE_PROP_BIT("host_ecn", _state, _field, VIRTIO_NET_F_HOST_ECN, true), \


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [RFC v3 PATCH 4/4] virtio-net: compat guest announce support.
  2011-10-27  8:48 [RFC v3 PATCH 0/4] Send gratuitous packets by guest Jason Wang
                   ` (2 preceding siblings ...)
  2011-10-27  8:48 ` [RFC v3 PATCH 3/4] virtio-net: notify guest to annouce itself Jason Wang
@ 2011-10-27  8:49 ` Jason Wang
  3 siblings, 0 replies; 5+ messages in thread
From: Jason Wang @ 2011-10-27  8:49 UTC (permalink / raw)
  To: aliguori, mst, jan.kiszka, rusty, qemu-devel, blauwirbel, stefanha
  Cc: netdev, kvm

Disable guest announce for compat machine types.

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

diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index 8c7f2b7..6ca50a6 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -340,6 +340,10 @@ static QEMUMachine pc_machine_v0_13 = {
             .driver   = "virtio-net-pci",
             .property = "event_idx",
             .value    = "off",
+        },{
+            .driver   = "virtio-net-pci",
+            .property = "guest_announce",
+            .value    = "off",
         },
         { /* end of list */ }
     },
@@ -383,6 +387,10 @@ static QEMUMachine pc_machine_v0_12 = {
             .driver   = "virtio-net-pci",
             .property = "event_idx",
             .value    = "off",
+        },{
+            .driver   = "virtio-net-pci",
+            .property = "guest_announce",
+            .value    = "off",
         },
         { /* end of list */ }
     }
@@ -434,6 +442,10 @@ static QEMUMachine pc_machine_v0_11 = {
             .driver   = "virtio-net-pci",
             .property = "event_idx",
             .value    = "off",
+        },{
+            .driver   = "virtio-net-pci",
+            .property = "guest_announce",
+            .value    = "off",
         },
         { /* end of list */ }
     }
@@ -497,6 +509,10 @@ static QEMUMachine pc_machine_v0_10 = {
             .driver   = "virtio-net-pci",
             .property = "event_idx",
             .value    = "off",
+        },{
+            .driver   = "virtio-net-pci",
+            .property = "guest_announce",
+            .value    = "off",
         },
         { /* end of list */ }
     },


^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2011-10-27  8:49 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-10-27  8:48 [RFC v3 PATCH 0/4] Send gratuitous packets by guest Jason Wang
2011-10-27  8:48 ` [RFC v3 PATCH 1/4] announce self after vm start Jason Wang
2011-10-27  8:48 ` [RFC v3 PATCH 2/4] net: model specific announcing support Jason Wang
2011-10-27  8:48 ` [RFC v3 PATCH 3/4] virtio-net: notify guest to annouce itself Jason Wang
2011-10-27  8:49 ` [RFC v3 PATCH 4/4] virtio-net: compat guest announce support Jason Wang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).