summaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
authorDr. David Alan Gilbert <dgilbert@redhat.com>2019-02-27 13:24:08 +0000
committerJason Wang <jasowang@redhat.com>2019-03-05 11:27:41 +0800
commit7659505c1680643d13ad7675f9e649d388303059 (patch)
tree502da4c1b4ba4b5397727810385c2fe8ca6eb4ad /net
parent9d8c6a258c70d8ff494489140a4fcb3a965909b2 (diff)
migration: Switch to using announce timer
Switch the announcements to using the new announce timer. Move the code that does it to announce.c rather than savevm because it really has nothing to do with the actual migration. Migration starts the announce from bh's and so they're all in the main thread/bql, and so there's never any racing with the timers themselves. Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Jason Wang <jasowang@redhat.com>
Diffstat (limited to 'net')
-rw-r--r--net/announce.c68
-rw-r--r--net/trace-events3
2 files changed, 71 insertions, 0 deletions
diff --git a/net/announce.c b/net/announce.c
index 8876eb62b6..13ad9c2ba8 100644
--- a/net/announce.c
+++ b/net/announce.c
@@ -9,8 +9,10 @@
#include "qemu/osdep.h"
#include "qemu-common.h"
#include "net/announce.h"
+#include "net/net.h"
#include "qapi/clone-visitor.h"
#include "qapi/qapi-visit-net.h"
+#include "trace.h"
int64_t qemu_announce_timer_step(AnnounceTimer *timer)
{
@@ -58,3 +60,69 @@ void qemu_announce_timer_reset(AnnounceTimer *timer,
timer->type = type;
timer->tm = timer_new_ms(type, cb, opaque);
}
+
+#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];
+ int len;
+
+ trace_qemu_announce_self_iter(qemu_ether_ntoa(&nic->conf->macaddr));
+ len = announce_self_create(buf, nic->conf->macaddr.a);
+
+ qemu_send_packet_raw(qemu_get_queue(nic), buf, len);
+}
+static void qemu_announce_self_once(void *opaque)
+{
+ AnnounceTimer *timer = (AnnounceTimer *)opaque;
+
+ qemu_foreach_nic(qemu_announce_self_iter, NULL);
+
+ if (--timer->round) {
+ qemu_announce_timer_step(timer);
+ } else {
+ qemu_announce_timer_del(timer);
+ }
+}
+
+void qemu_announce_self(AnnounceTimer *timer, AnnounceParameters *params)
+{
+ qemu_announce_timer_reset(timer, params, QEMU_CLOCK_REALTIME,
+ qemu_announce_self_once, timer);
+ if (params->rounds) {
+ qemu_announce_self_once(timer);
+ } else {
+ qemu_announce_timer_del(timer);
+ }
+}
diff --git a/net/trace-events b/net/trace-events
index 7b594cfdd2..3417ac05b0 100644
--- a/net/trace-events
+++ b/net/trace-events
@@ -1,5 +1,8 @@
# See docs/devel/tracing.txt for syntax documentation.
+# net/announce.c
+qemu_announce_self_iter(const char *mac) "%s"
+
# net/vhost-user.c
vhost_user_event(const char *chr, int event) "chr: %s got event: %d"