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

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 connection may lost or stall 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 in order to solve this issue, the best method 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 function and then implement a virtio-net specific function to
let guest send the gratitous packet.

Only basic test were done.

Comments are welcomed.

Thanks

---

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


 hw/virtio-net.c |   20 +++++++++++++++++++-
 hw/virtio-net.h |    2 ++
 migration.c     |    1 -
 net.c           |   31 +++++++++++++++++++++++++++++++
 net.h           |    3 +++
 savevm.c        |   40 +++++-----------------------------------
 vl.c            |    1 +
 7 files changed, 61 insertions(+), 37 deletions(-)

-- 
Jason Wang

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

* [RFC v2 PATCH 1/4] announce self after vm start
  2011-10-22  5:38 [RFC v2 PATCH 0/4] Support sending gratuitous by guest Jason Wang
@ 2011-10-22  5:38 ` Jason Wang
  2011-10-22  5:38 ` [RFC v2 PATCH 2/4] net: export announce_self_create() Jason Wang
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 6+ messages in thread
From: Jason Wang @ 2011-10-22  5:38 UTC (permalink / raw)
  To: aliguori, quintela, jan.kiszka, mst, qemu-devel, blauwirbel
  Cc: pbonzini, rusty, kvm, netdev

We send gratituous packets to let switch to update its mac address
table, this is only done after migration currently because guest may
move to the host with another port connect to switch.

Unfortunately this kind of notification is also needed for continue a
stopped vm as the mac address table entry may not existed because of
aging. This patch solve this by call qemu_announce_self() in
vm_start() instead of in process_incoming_migration(). Through this,
gratituous packets were sent each time when vm starts.

Signed-off-by: Jason Wang <jasowang@redhat.com>
---
 migration.c |    1 -
 vl.c        |    1 +
 2 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/migration.c b/migration.c
index 77a51ad..3326b02 100644
--- a/migration.c
+++ b/migration.c
@@ -67,7 +67,6 @@ void process_incoming_migration(QEMUFile *f)
         fprintf(stderr, "load of migration failed\n");
         exit(0);
     }
-    qemu_announce_self();
     DPRINTF("successfully loaded vm state\n");
 
     if (autostart) {
diff --git a/vl.c b/vl.c
index dbf7778..e4408e0 100644
--- a/vl.c
+++ b/vl.c
@@ -1262,6 +1262,7 @@ void vm_start(void)
         vm_state_notify(1, RUN_STATE_RUNNING);
         resume_all_vcpus();
         monitor_protocol_event(QEVENT_RESUME, NULL);
+        qemu_announce_self();
     }
 }
 

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

* [RFC v2 PATCH 2/4] net: export announce_self_create()
  2011-10-22  5:38 [RFC v2 PATCH 0/4] Support sending gratuitous by guest Jason Wang
  2011-10-22  5:38 ` [RFC v2 PATCH 1/4] announce self after vm start Jason Wang
@ 2011-10-22  5:38 ` Jason Wang
  2011-10-22  5:38 ` [RFC v2 PATCH 3/4] net: model specific announcing support Jason Wang
  2011-10-22  5:39 ` [RFC v2 PATCH 4/4] virtio-net: notify guest to annouce itself Jason Wang
  3 siblings, 0 replies; 6+ messages in thread
From: Jason Wang @ 2011-10-22  5:38 UTC (permalink / raw)
  To: aliguori, quintela, jan.kiszka, mst, qemu-devel, blauwirbel
  Cc: pbonzini, rusty, kvm, netdev

Export and move announce_self_create() to net.c in order to be used by model
specific announcing function.

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

diff --git a/net.c b/net.c
index d05930c..516ff9e 100644
--- a/net.c
+++ b/net.c
@@ -42,6 +42,37 @@ static QTAILQ_HEAD(, VLANClientState) non_vlan_clients;
 
 int default_net = 1;
 
+#ifndef ETH_P_RARP
+#define ETH_P_RARP 0x8035
+#endif
+#define ARP_HTYPE_ETH 0x0001
+#define ARP_PTYPE_IP 0x0800
+#define ARP_OP_REQUEST_REV 0x3
+
+int announce_self_create(uint8_t *buf, uint8_t *mac_addr)
+{
+    /* Ethernet header. */
+    memset(buf, 0xff, 6);         /* destination MAC addr */
+    memcpy(buf + 6, mac_addr, 6); /* source MAC addr */
+    *(uint16_t *)(buf + 12) = htons(ETH_P_RARP); /* ethertype */
+
+    /* RARP header. */
+    *(uint16_t *)(buf + 14) = htons(ARP_HTYPE_ETH); /* hardware addr space */
+    *(uint16_t *)(buf + 16) = htons(ARP_PTYPE_IP); /* protocol addr space */
+    *(buf + 18) = 6; /* hardware addr length (ethernet) */
+    *(buf + 19) = 4; /* protocol addr length (IPv4) */
+    *(uint16_t *)(buf + 20) = htons(ARP_OP_REQUEST_REV); /* opcode */
+    memcpy(buf + 22, mac_addr, 6); /* source hw addr */
+    memset(buf + 28, 0x00, 4);     /* source protocol addr */
+    memcpy(buf + 32, mac_addr, 6); /* target hw addr */
+    memset(buf + 38, 0x00, 4);     /* target protocol addr */
+
+    /* Padding to get up to 60 bytes (ethernet min packet size, minus FCS). */
+    memset(buf + 42, 0x00, 18);
+
+    return 60; /* len (FCS will be added by hardware) */
+}
+
 /***********************************************************/
 /* network device redirectors */
 
diff --git a/net.h b/net.h
index 9f633f8..4943d4b 100644
--- a/net.h
+++ b/net.h
@@ -178,5 +178,6 @@ int do_netdev_del(Monitor *mon, const QDict *qdict, QObject **ret_data);
 void qdev_set_nic_properties(DeviceState *dev, NICInfo *nd);
 
 int net_handle_fd_param(Monitor *mon, const char *param);
+int announce_self_create(uint8_t *buf, uint8_t *mac_addr);
 
 #endif
diff --git a/savevm.c b/savevm.c
index bf4d0e7..8293ee6 100644
--- a/savevm.c
+++ b/savevm.c
@@ -85,38 +85,6 @@
 
 #define SELF_ANNOUNCE_ROUNDS 5
 
-#ifndef ETH_P_RARP
-#define ETH_P_RARP 0x8035
-#endif
-#define ARP_HTYPE_ETH 0x0001
-#define ARP_PTYPE_IP 0x0800
-#define ARP_OP_REQUEST_REV 0x3
-
-static int announce_self_create(uint8_t *buf,
-				uint8_t *mac_addr)
-{
-    /* Ethernet header. */
-    memset(buf, 0xff, 6);         /* destination MAC addr */
-    memcpy(buf + 6, mac_addr, 6); /* source MAC addr */
-    *(uint16_t *)(buf + 12) = htons(ETH_P_RARP); /* ethertype */
-
-    /* RARP header. */
-    *(uint16_t *)(buf + 14) = htons(ARP_HTYPE_ETH); /* hardware addr space */
-    *(uint16_t *)(buf + 16) = htons(ARP_PTYPE_IP); /* protocol addr space */
-    *(buf + 18) = 6; /* hardware addr length (ethernet) */
-    *(buf + 19) = 4; /* protocol addr length (IPv4) */
-    *(uint16_t *)(buf + 20) = htons(ARP_OP_REQUEST_REV); /* opcode */
-    memcpy(buf + 22, mac_addr, 6); /* source hw addr */
-    memset(buf + 28, 0x00, 4);     /* source protocol addr */
-    memcpy(buf + 32, mac_addr, 6); /* target hw addr */
-    memset(buf + 38, 0x00, 4);     /* target protocol addr */
-
-    /* Padding to get up to 60 bytes (ethernet min packet size, minus FCS). */
-    memset(buf + 42, 0x00, 18);
-
-    return 60; /* len (FCS will be added by hardware) */
-}
-
 static void qemu_announce_self_iter(NICState *nic, void *opaque)
 {
     uint8_t buf[60];


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

* [RFC v2 PATCH 3/4] net: model specific announcing support
  2011-10-22  5:38 [RFC v2 PATCH 0/4] Support sending gratuitous by guest Jason Wang
  2011-10-22  5:38 ` [RFC v2 PATCH 1/4] announce self after vm start Jason Wang
  2011-10-22  5:38 ` [RFC v2 PATCH 2/4] net: export announce_self_create() Jason Wang
@ 2011-10-22  5:38 ` Jason Wang
  2011-10-22  5:39 ` [RFC v2 PATCH 4/4] virtio-net: notify guest to annouce itself Jason Wang
  3 siblings, 0 replies; 6+ messages in thread
From: Jason Wang @ 2011-10-22  5:38 UTC (permalink / raw)
  To: aliguori, quintela, jan.kiszka, mst, qemu-devel, blauwirbel
  Cc: pbonzini, rusty, kvm, netdev

This patch introduce a function pointer in NetClientInfo which is
called during self announcement to do the model specific announcement
such as sending gratuitous packet. Previous method is kept when model
specific announcing fails or without it.

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 4943d4b..1845f01 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 8293ee6..de6a01a 100644
--- a/savevm.c
+++ b/savevm.c
@@ -89,10 +89,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] 6+ messages in thread

* [RFC v2 PATCH 4/4] virtio-net: notify guest to annouce itself
  2011-10-22  5:38 [RFC v2 PATCH 0/4] Support sending gratuitous by guest Jason Wang
                   ` (2 preceding siblings ...)
  2011-10-22  5:38 ` [RFC v2 PATCH 3/4] net: model specific announcing support Jason Wang
@ 2011-10-22  5:39 ` Jason Wang
  2011-10-26  6:19   ` [Qemu-devel] " Stefan Hajnoczi
  3 siblings, 1 reply; 6+ messages in thread
From: Jason Wang @ 2011-10-22  5:39 UTC (permalink / raw)
  To: aliguori, quintela, jan.kiszka, mst, qemu-devel, blauwirbel
  Cc: pbonzini, rusty, kvm, netdev

It's hard to track all mac address and its usage (vlan, bondings,
ipv6) in qemu to send gratituous packet in qemu side, so the better
choice is let guest 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 itself
( such as sending gratituous packets ) through config update
interrupt. When gust have done the annoucement, it should clear that
bit.

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

diff --git a/hw/virtio-net.c b/hw/virtio-net.c
index 8c2f460..7f844e7 100644
--- a/hw/virtio-net.c
+++ b/hw/virtio-net.c
@@ -95,6 +95,10 @@ 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);
     }
+
+    if (memcmp(&netcfg.status, &n->status, sizeof(n->status))) {
+        memcpy(&n->status, &netcfg.status, sizeof(n->status));
+    }
 }
 
 static bool virtio_net_started(VirtIONet *n, uint8_t status)
@@ -227,7 +231,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 +987,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 |= VIRITO_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 +1007,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..c47bd52 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 VIRITO_NET_S_ANNOUNCE   2       /* Announcement is needed */
 
 #define TX_TIMER_INTERVAL 150000 /* 150 us */
 


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

* Re: [Qemu-devel] [RFC v2 PATCH 4/4] virtio-net: notify guest to annouce itself
  2011-10-22  5:39 ` [RFC v2 PATCH 4/4] virtio-net: notify guest to annouce itself Jason Wang
@ 2011-10-26  6:19   ` Stefan Hajnoczi
  0 siblings, 0 replies; 6+ messages in thread
From: Stefan Hajnoczi @ 2011-10-26  6:19 UTC (permalink / raw)
  To: Jason Wang
  Cc: aliguori, quintela, jan.kiszka, mst, qemu-devel, blauwirbel,
	pbonzini, rusty, kvm, netdev

On Fri, Oct 21, 2011 at 10:39 PM, Jason Wang <jasowang@redhat.com> wrote:
> diff --git a/hw/virtio-net.c b/hw/virtio-net.c
> index 8c2f460..7f844e7 100644
> --- a/hw/virtio-net.c
> +++ b/hw/virtio-net.c
> @@ -95,6 +95,10 @@ 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);
>     }
> +
> +    if (memcmp(&netcfg.status, &n->status, sizeof(n->status))) {
> +        memcpy(&n->status, &netcfg.status, sizeof(n->status));
> +    }

The memcpy() can be done unconditionally.

>  }
>
>  static bool virtio_net_started(VirtIONet *n, uint8_t status)
> @@ -227,7 +231,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 +987,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 |= VIRITO_NET_S_ANNOUNCE;

Typo, should be VIRTIO_NET_S_ANNOUNCE.

Stefan

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

end of thread, other threads:[~2011-10-26  6:19 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-10-22  5:38 [RFC v2 PATCH 0/4] Support sending gratuitous by guest Jason Wang
2011-10-22  5:38 ` [RFC v2 PATCH 1/4] announce self after vm start Jason Wang
2011-10-22  5:38 ` [RFC v2 PATCH 2/4] net: export announce_self_create() Jason Wang
2011-10-22  5:38 ` [RFC v2 PATCH 3/4] net: model specific announcing support Jason Wang
2011-10-22  5:39 ` [RFC v2 PATCH 4/4] virtio-net: notify guest to annouce itself Jason Wang
2011-10-26  6:19   ` [Qemu-devel] " Stefan Hajnoczi

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