]> Git Repo - qemu.git/blame - net/announce.c
migration: Switch to using announce timer
[qemu.git] / net / announce.c
CommitLineData
50510ea2
DDAG
1/*
2 * Self-announce
3 * (c) 2017-2019 Red Hat, Inc.
4 *
5 * This work is licensed under the terms of the GNU GPL, version 2 or later.
6 * See the COPYING file in the top-level directory.
7 */
8
9#include "qemu/osdep.h"
10#include "qemu-common.h"
11#include "net/announce.h"
7659505c 12#include "net/net.h"
50510ea2
DDAG
13#include "qapi/clone-visitor.h"
14#include "qapi/qapi-visit-net.h"
7659505c 15#include "trace.h"
50510ea2
DDAG
16
17int64_t qemu_announce_timer_step(AnnounceTimer *timer)
18{
19 int64_t step;
20
21 step = timer->params.initial +
22 (timer->params.rounds - timer->round - 1) *
23 timer->params.step;
24
25 if (step < 0 || step > timer->params.max) {
26 step = timer->params.max;
27 }
28 timer_mod(timer->tm, qemu_clock_get_ms(timer->type) + step);
29
30 return step;
31}
32
33void qemu_announce_timer_del(AnnounceTimer *timer)
34{
35 if (timer->tm) {
36 timer_del(timer->tm);
37 timer_free(timer->tm);
38 timer->tm = NULL;
39 }
40}
41
42/*
43 * Under BQL/main thread
44 * Reset the timer to the given parameters/type/notifier.
45 */
46void qemu_announce_timer_reset(AnnounceTimer *timer,
47 AnnounceParameters *params,
48 QEMUClockType type,
49 QEMUTimerCB *cb,
50 void *opaque)
51{
52 /*
53 * We're under the BQL, so the current timer can't
54 * be firing, so we should be able to delete it.
55 */
56 qemu_announce_timer_del(timer);
57
58 QAPI_CLONE_MEMBERS(AnnounceParameters, &timer->params, params);
59 timer->round = params->rounds;
60 timer->type = type;
61 timer->tm = timer_new_ms(type, cb, opaque);
62}
7659505c
DDAG
63
64#ifndef ETH_P_RARP
65#define ETH_P_RARP 0x8035
66#endif
67#define ARP_HTYPE_ETH 0x0001
68#define ARP_PTYPE_IP 0x0800
69#define ARP_OP_REQUEST_REV 0x3
70
71static int announce_self_create(uint8_t *buf,
72 uint8_t *mac_addr)
73{
74 /* Ethernet header. */
75 memset(buf, 0xff, 6); /* destination MAC addr */
76 memcpy(buf + 6, mac_addr, 6); /* source MAC addr */
77 *(uint16_t *)(buf + 12) = htons(ETH_P_RARP); /* ethertype */
78
79 /* RARP header. */
80 *(uint16_t *)(buf + 14) = htons(ARP_HTYPE_ETH); /* hardware addr space */
81 *(uint16_t *)(buf + 16) = htons(ARP_PTYPE_IP); /* protocol addr space */
82 *(buf + 18) = 6; /* hardware addr length (ethernet) */
83 *(buf + 19) = 4; /* protocol addr length (IPv4) */
84 *(uint16_t *)(buf + 20) = htons(ARP_OP_REQUEST_REV); /* opcode */
85 memcpy(buf + 22, mac_addr, 6); /* source hw addr */
86 memset(buf + 28, 0x00, 4); /* source protocol addr */
87 memcpy(buf + 32, mac_addr, 6); /* target hw addr */
88 memset(buf + 38, 0x00, 4); /* target protocol addr */
89
90 /* Padding to get up to 60 bytes (ethernet min packet size, minus FCS). */
91 memset(buf + 42, 0x00, 18);
92
93 return 60; /* len (FCS will be added by hardware) */
94}
95
96static void qemu_announce_self_iter(NICState *nic, void *opaque)
97{
98 uint8_t buf[60];
99 int len;
100
101 trace_qemu_announce_self_iter(qemu_ether_ntoa(&nic->conf->macaddr));
102 len = announce_self_create(buf, nic->conf->macaddr.a);
103
104 qemu_send_packet_raw(qemu_get_queue(nic), buf, len);
105}
106static void qemu_announce_self_once(void *opaque)
107{
108 AnnounceTimer *timer = (AnnounceTimer *)opaque;
109
110 qemu_foreach_nic(qemu_announce_self_iter, NULL);
111
112 if (--timer->round) {
113 qemu_announce_timer_step(timer);
114 } else {
115 qemu_announce_timer_del(timer);
116 }
117}
118
119void qemu_announce_self(AnnounceTimer *timer, AnnounceParameters *params)
120{
121 qemu_announce_timer_reset(timer, params, QEMU_CLOCK_REALTIME,
122 qemu_announce_self_once, timer);
123 if (params->rounds) {
124 qemu_announce_self_once(timer);
125 } else {
126 qemu_announce_timer_del(timer);
127 }
128}
This page took 0.034234 seconds and 4 git commands to generate.