master
c 665 lines 20.7 KB
Raw
1 /*
2 * xen paravirt network card backend
3 *
4 * (c) Gerd Hoffmann <kraxel@redhat.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; under version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, see <http://www.gnu.org/licenses/>.
17 *
18 * Contributions after 2012-01-13 are licensed under the terms of the
19 * GNU GPL, version 2 or (at your option) any later version.
20 */
21
22 #include "qemu/osdep.h"
23 #include "qemu/main-loop.h"
24 #include "qemu/cutils.h"
25 #include "qemu/log.h"
26 #include "qemu/qemu-print.h"
27 #include "qobject/qdict.h"
28 #include "qapi/error.h"
29
30 #include <sys/socket.h>
31 #include <sys/ioctl.h>
32 #include <sys/wait.h>
33
34 #include "net/net.h"
35 #include "net/checksum.h"
36 #include "net/util.h"
37
38 #include "hw/xen/xen-backend.h"
39 #include "hw/xen/xen-bus-helper.h"
40 #include "hw/core/qdev-properties.h"
41 #include "hw/core/qdev-properties-system.h"
42
43 #include "hw/xen/interface/io/netif.h"
44 #include "hw/xen/interface/io/xs_wire.h"
45
46 #include "trace.h"
47
48 /* ------------------------------------------------------------- */
49
50 struct XenNetDev {
51 struct XenDevice xendev; /* must be first */
52 XenEventChannel *event_channel;
53 int dev;
54 int tx_work;
55 unsigned int tx_ring_ref;
56 unsigned int rx_ring_ref;
57 struct netif_tx_sring *txs;
58 struct netif_rx_sring *rxs;
59 netif_tx_back_ring_t tx_ring;
60 netif_rx_back_ring_t rx_ring;
61 NICConf conf;
62 NICState *nic;
63 };
64
65 #define TYPE_XEN_NET_DEVICE "xen-net-device"
66 OBJECT_DECLARE_SIMPLE_TYPE(XenNetDev, XEN_NET_DEVICE)
67
68 /* ------------------------------------------------------------- */
69
70 static void net_tx_response(struct XenNetDev *netdev, netif_tx_request_t *txp, int8_t st)
71 {
72 RING_IDX i = netdev->tx_ring.rsp_prod_pvt;
73 netif_tx_response_t *resp;
74 int notify;
75
76 resp = RING_GET_RESPONSE(&netdev->tx_ring, i);
77 resp->id = txp->id;
78 resp->status = st;
79
80 #if 0
81 if (txp->flags & NETTXF_extra_info) {
82 RING_GET_RESPONSE(&netdev->tx_ring, ++i)->status = NETIF_RSP_NULL;
83 }
84 #endif
85
86 netdev->tx_ring.rsp_prod_pvt = ++i;
87 RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&netdev->tx_ring, notify);
88 if (notify) {
89 xen_device_notify_event_channel(XEN_DEVICE(netdev),
90 netdev->event_channel, NULL);
91 }
92
93 if (i == netdev->tx_ring.req_cons) {
94 int more_to_do;
95 RING_FINAL_CHECK_FOR_REQUESTS(&netdev->tx_ring, more_to_do);
96 if (more_to_do) {
97 netdev->tx_work++;
98 }
99 }
100 }
101
102 static void net_tx_error(struct XenNetDev *netdev, netif_tx_request_t *txp, RING_IDX end)
103 {
104 #if 0
105 /*
106 * Hmm, why netback fails everything in the ring?
107 * Should we do that even when not supporting SG and TSO?
108 */
109 RING_IDX cons = netdev->tx_ring.req_cons;
110
111 do {
112 make_tx_response(netif, txp, NETIF_RSP_ERROR);
113 if (cons >= end) {
114 break;
115 }
116 txp = RING_GET_REQUEST(&netdev->tx_ring, cons++);
117 } while (1);
118 netdev->tx_ring.req_cons = cons;
119 netif_schedule_work(netif);
120 netif_put(netif);
121 #else
122 net_tx_response(netdev, txp, NETIF_RSP_ERROR);
123 #endif
124 }
125
126 static bool net_tx_packets(struct XenNetDev *netdev)
127 {
128 bool done_something = false;
129 netif_tx_request_t txreq;
130 RING_IDX rc, rp;
131 void *page;
132 void *tmpbuf = NULL;
133
134 assert(bql_locked());
135
136 for (;;) {
137 rc = netdev->tx_ring.req_cons;
138 rp = netdev->tx_ring.sring->req_prod;
139 xen_rmb(); /* Ensure we see queued requests up to 'rp'. */
140
141 while ((rc != rp)) {
142 if (RING_REQUEST_CONS_OVERFLOW(&netdev->tx_ring, rc)) {
143 break;
144 }
145 memcpy(&txreq, RING_GET_REQUEST(&netdev->tx_ring, rc), sizeof(txreq));
146 netdev->tx_ring.req_cons = ++rc;
147 done_something = true;
148
149 #if 1
150 /* should not happen in theory, we don't announce the *
151 * feature-{sg,gso,whatelse} flags in xenstore (yet?) */
152 if (txreq.flags & NETTXF_extra_info) {
153 qemu_log_mask(LOG_UNIMP, "vif%u: FIXME: extra info flag\n",
154 netdev->dev);
155 net_tx_error(netdev, &txreq, rc);
156 continue;
157 }
158 if (txreq.flags & NETTXF_more_data) {
159 qemu_log_mask(LOG_UNIMP, "vif%u: FIXME: more data flag\n",
160 netdev->dev);
161 net_tx_error(netdev, &txreq, rc);
162 continue;
163 }
164 #endif
165
166 if (txreq.size < 14) {
167 qemu_log_mask(LOG_GUEST_ERROR, "vif%u: bad packet size: %d\n",
168 netdev->dev, txreq.size);
169 net_tx_error(netdev, &txreq, rc);
170 continue;
171 }
172
173 if ((txreq.offset + txreq.size) > XEN_PAGE_SIZE) {
174 qemu_log_mask(LOG_GUEST_ERROR, "vif%u: error: page crossing\n",
175 netdev->dev);
176 net_tx_error(netdev, &txreq, rc);
177 continue;
178 }
179
180 trace_xen_netdev_tx(netdev->dev, txreq.gref, txreq.offset,
181 txreq.size, txreq.flags,
182 (txreq.flags & NETTXF_csum_blank) ? " csum_blank" : "",
183 (txreq.flags & NETTXF_data_validated) ? " data_validated" : "",
184 (txreq.flags & NETTXF_more_data) ? " more_data" : "",
185 (txreq.flags & NETTXF_extra_info) ? " extra_info" : "");
186
187 page = xen_device_map_grant_refs(&netdev->xendev, &txreq.gref, 1,
188 PROT_READ, NULL);
189 if (page == NULL) {
190 qemu_log_mask(LOG_GUEST_ERROR,
191 "vif%u: tx gref dereference failed (%d)\n",
192 netdev->dev, txreq.gref);
193 net_tx_error(netdev, &txreq, rc);
194 continue;
195 }
196 if (txreq.flags & NETTXF_csum_blank) {
197 /* have read-only mapping -> can't fill checksum in-place */
198 if (!tmpbuf) {
199 tmpbuf = g_malloc(XEN_PAGE_SIZE);
200 }
201 memcpy(tmpbuf, page + txreq.offset, txreq.size);
202 net_checksum_calculate(tmpbuf, txreq.size, CSUM_ALL);
203 qemu_send_packet(qemu_get_queue(netdev->nic), tmpbuf,
204 txreq.size);
205 } else {
206 qemu_send_packet(qemu_get_queue(netdev->nic),
207 page + txreq.offset, txreq.size);
208 }
209 xen_device_unmap_grant_refs(&netdev->xendev, page, &txreq.gref, 1,
210 NULL);
211 net_tx_response(netdev, &txreq, NETIF_RSP_OKAY);
212 }
213 if (!netdev->tx_work) {
214 break;
215 }
216 netdev->tx_work = 0;
217 }
218 g_free(tmpbuf);
219 return done_something;
220 }
221
222 /* ------------------------------------------------------------- */
223
224 static void net_rx_response(struct XenNetDev *netdev,
225 netif_rx_request_t *req, int8_t st,
226 uint16_t offset, uint16_t size,
227 uint16_t flags)
228 {
229 RING_IDX i = netdev->rx_ring.rsp_prod_pvt;
230 netif_rx_response_t *resp;
231 int notify;
232
233 resp = RING_GET_RESPONSE(&netdev->rx_ring, i);
234 resp->offset = offset;
235 resp->flags = flags;
236 resp->id = req->id;
237 resp->status = (int16_t)size;
238 if (st < 0) {
239 resp->status = (int16_t)st;
240 }
241
242 trace_xen_netdev_rx(netdev->dev, i, resp->status, resp->flags);
243
244 netdev->rx_ring.rsp_prod_pvt = ++i;
245 RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&netdev->rx_ring, notify);
246 if (notify) {
247 xen_device_notify_event_channel(XEN_DEVICE(netdev),
248 netdev->event_channel, NULL);
249 }
250 }
251
252 #define NET_IP_ALIGN 2
253
254 static ssize_t net_rx_packet(NetClientState *nc, const uint8_t *buf, size_t size)
255 {
256 struct XenNetDev *netdev = qemu_get_nic_opaque(nc);
257 netif_rx_request_t rxreq;
258 RING_IDX rc, rp;
259 void *page;
260
261 assert(bql_locked());
262
263 if (xen_device_backend_get_state(&netdev->xendev) != XenbusStateConnected) {
264 return -1;
265 }
266
267 rc = netdev->rx_ring.req_cons;
268 rp = netdev->rx_ring.sring->req_prod;
269 xen_rmb(); /* Ensure we see queued requests up to 'rp'. */
270
271 if (rc == rp || RING_REQUEST_CONS_OVERFLOW(&netdev->rx_ring, rc)) {
272 return 0;
273 }
274 if (size > XEN_PAGE_SIZE - NET_IP_ALIGN) {
275 qemu_log_mask(LOG_GUEST_ERROR, "vif%u: packet too big (%lu > %ld)",
276 netdev->dev, (unsigned long)size,
277 XEN_PAGE_SIZE - NET_IP_ALIGN);
278 return -1;
279 }
280
281 memcpy(&rxreq, RING_GET_REQUEST(&netdev->rx_ring, rc), sizeof(rxreq));
282 netdev->rx_ring.req_cons = ++rc;
283
284 page = xen_device_map_grant_refs(&netdev->xendev, &rxreq.gref, 1,
285 PROT_WRITE, NULL);
286 if (page == NULL) {
287 qemu_log_mask(LOG_GUEST_ERROR,
288 "vif%u: rx gref dereference failed (%d)\n",
289 netdev->dev, rxreq.gref);
290 net_rx_response(netdev, &rxreq, NETIF_RSP_ERROR, 0, 0, 0);
291 return -1;
292 }
293 memcpy(page + NET_IP_ALIGN, buf, size);
294 xen_device_unmap_grant_refs(&netdev->xendev, page, &rxreq.gref, 1, NULL);
295 net_rx_response(netdev, &rxreq, NETIF_RSP_OKAY, NET_IP_ALIGN, size, 0);
296
297 return size;
298 }
299
300 /* ------------------------------------------------------------- */
301
302 static NetClientInfo net_xen_info = {
303 .type = NET_CLIENT_DRIVER_NIC,
304 .size = sizeof(NICState),
305 .receive = net_rx_packet,
306 };
307
308 static void xen_netdev_realize(XenDevice *xendev, Error **errp)
309 {
310 ERRP_GUARD();
311 XenNetDev *netdev = XEN_NET_DEVICE(xendev);
312 NetClientState *nc;
313
314 qemu_macaddr_default_if_unset(&netdev->conf.macaddr);
315
316 xen_device_frontend_printf(xendev, "mac", "%02x:%02x:%02x:%02x:%02x:%02x",
317 netdev->conf.macaddr.a[0],
318 netdev->conf.macaddr.a[1],
319 netdev->conf.macaddr.a[2],
320 netdev->conf.macaddr.a[3],
321 netdev->conf.macaddr.a[4],
322 netdev->conf.macaddr.a[5]);
323
324 netdev->nic = qemu_new_nic(&net_xen_info, &netdev->conf,
325 object_get_typename(OBJECT(xendev)),
326 DEVICE(xendev)->id,
327 &xendev->qdev.mem_reentrancy_guard, netdev);
328
329 nc = qemu_get_queue(netdev->nic);
330 qemu_format_nic_info_str(nc, netdev->conf.macaddr.a);
331
332 /* fill info */
333 xen_device_backend_printf(xendev, "feature-rx-copy", "%u", 1);
334 xen_device_backend_printf(xendev, "feature-rx-flip", "%u", 0);
335
336 trace_xen_netdev_realize(netdev->dev, nc->info_str, nc->peer ?
337 nc->peer->name : "(none)");
338 }
339
340 static bool net_event(void *_xendev)
341 {
342 XenNetDev *netdev = XEN_NET_DEVICE(_xendev);
343 bool done_something;
344
345 done_something = net_tx_packets(netdev);
346 qemu_flush_queued_packets(qemu_get_queue(netdev->nic));
347 return done_something;
348 }
349
350 static bool xen_netdev_connect(XenDevice *xendev, Error **errp)
351 {
352 ERRP_GUARD();
353 XenNetDev *netdev = XEN_NET_DEVICE(xendev);
354 unsigned int port, rx_copy;
355
356 assert(bql_locked());
357
358 if (xen_device_frontend_scanf(xendev, "tx-ring-ref", "%u",
359 &netdev->tx_ring_ref) != 1) {
360 error_setg(errp, "failed to read tx-ring-ref");
361 return false;
362 }
363
364 if (xen_device_frontend_scanf(xendev, "rx-ring-ref", "%u",
365 &netdev->rx_ring_ref) != 1) {
366 error_setg(errp, "failed to read rx-ring-ref");
367 return false;
368 }
369
370 if (xen_device_frontend_scanf(xendev, "event-channel", "%u",
371 &port) != 1) {
372 error_setg(errp, "failed to read event-channel");
373 return false;
374 }
375
376 if (xen_device_frontend_scanf(xendev, "request-rx-copy", "%u",
377 &rx_copy) != 1) {
378 rx_copy = 0;
379 }
380 if (rx_copy == 0) {
381 error_setg(errp, "frontend doesn't support rx-copy");
382 return false;
383 }
384
385 netdev->txs = xen_device_map_grant_refs(xendev,
386 &netdev->tx_ring_ref, 1,
387 PROT_READ | PROT_WRITE,
388 errp);
389 if (!netdev->txs) {
390 error_prepend(errp, "failed to map tx grant ref: ");
391 return false;
392 }
393
394 netdev->rxs = xen_device_map_grant_refs(xendev,
395 &netdev->rx_ring_ref, 1,
396 PROT_READ | PROT_WRITE,
397 errp);
398 if (!netdev->rxs) {
399 error_prepend(errp, "failed to map rx grant ref: ");
400 return false;
401 }
402
403 BACK_RING_INIT(&netdev->tx_ring, netdev->txs, XEN_PAGE_SIZE);
404 BACK_RING_INIT(&netdev->rx_ring, netdev->rxs, XEN_PAGE_SIZE);
405
406 netdev->event_channel = xen_device_bind_event_channel(xendev, port,
407 net_event,
408 netdev,
409 errp);
410 if (!netdev->event_channel) {
411 return false;
412 }
413
414 trace_xen_netdev_connect(netdev->dev, netdev->tx_ring_ref,
415 netdev->rx_ring_ref, port);
416
417 net_tx_packets(netdev);
418 return true;
419 }
420
421 static void xen_netdev_disconnect(XenDevice *xendev, Error **errp)
422 {
423 XenNetDev *netdev = XEN_NET_DEVICE(xendev);
424
425 trace_xen_netdev_disconnect(netdev->dev);
426
427 assert(bql_locked());
428
429 netdev->tx_ring.sring = NULL;
430 netdev->rx_ring.sring = NULL;
431
432 if (netdev->event_channel) {
433 xen_device_unbind_event_channel(xendev, netdev->event_channel,
434 errp);
435 netdev->event_channel = NULL;
436 }
437 if (netdev->txs) {
438 xen_device_unmap_grant_refs(xendev, netdev->txs,
439 &netdev->tx_ring_ref, 1, errp);
440 netdev->txs = NULL;
441 }
442 if (netdev->rxs) {
443 xen_device_unmap_grant_refs(xendev, netdev->rxs,
444 &netdev->rx_ring_ref, 1, errp);
445 netdev->rxs = NULL;
446 }
447 }
448
449 /* -------------------------------------------------------------------- */
450
451
452 static void xen_netdev_frontend_changed(XenDevice *xendev,
453 enum xenbus_state frontend_state,
454 Error **errp)
455 {
456 ERRP_GUARD();
457 enum xenbus_state backend_state = xen_device_backend_get_state(xendev);
458
459 trace_xen_netdev_frontend_changed(xendev->name, frontend_state);
460
461 switch (frontend_state) {
462 case XenbusStateConnected:
463 if (backend_state == XenbusStateConnected) {
464 break;
465 }
466
467 xen_netdev_disconnect(xendev, errp);
468 if (*errp) {
469 break;
470 }
471
472 if (!xen_netdev_connect(xendev, errp)) {
473 xen_netdev_disconnect(xendev, NULL);
474 xen_device_backend_set_state(xendev, XenbusStateClosing);
475 break;
476 }
477
478 xen_device_backend_set_state(xendev, XenbusStateConnected);
479 break;
480
481 case XenbusStateClosing:
482 xen_device_backend_set_state(xendev, XenbusStateClosing);
483 break;
484
485 case XenbusStateClosed:
486 case XenbusStateUnknown:
487 xen_netdev_disconnect(xendev, errp);
488 if (*errp) {
489 break;
490 }
491
492 xen_device_backend_set_state(xendev, XenbusStateClosed);
493 break;
494
495 case XenbusStateInitialised:
496 /*
497 * Linux netback does nothing on the frontend going (back) to
498 * XenbusStateInitialised, so do the same here.
499 */
500 default:
501 break;
502 }
503 }
504
505 static char *xen_netdev_get_name(XenDevice *xendev, Error **errp)
506 {
507 XenNetDev *netdev = XEN_NET_DEVICE(xendev);
508
509 if (netdev->dev == -1) {
510 XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
511 int idx = (xen_mode == XEN_EMULATE) ? 0 : 1;
512 Error *local_err = NULL;
513 char *value;
514
515 /* Theoretically we could go up to INT_MAX here but that's overkill */
516 while (idx < 100) {
517 value = xs_node_read(xenbus->xsh, XBT_NULL, NULL, &local_err,
518 "/local/domain/%u/device/vif/%u",
519 xendev->frontend_id, idx);
520 if (!value) {
521 if (errno == ENOENT) {
522 netdev->dev = idx;
523 error_free(local_err);
524 goto found;
525 }
526 error_propagate(errp, local_err);
527 return NULL;
528 }
529 free(value);
530 idx++;
531 }
532 error_setg(errp, "cannot find device index for netdev device");
533 return NULL;
534 }
535 found:
536 return g_strdup_printf("%u", netdev->dev);
537 }
538
539 static void xen_netdev_unrealize(XenDevice *xendev)
540 {
541 XenNetDev *netdev = XEN_NET_DEVICE(xendev);
542
543 trace_xen_netdev_unrealize(netdev->dev);
544
545 /* Disconnect from the frontend in case this has not already happened */
546 xen_netdev_disconnect(xendev, NULL);
547
548 if (netdev->nic) {
549 qemu_del_nic(netdev->nic);
550 }
551 }
552
553 /* ------------------------------------------------------------- */
554
555 static const Property xen_netdev_properties[] = {
556 DEFINE_NIC_PROPERTIES(XenNetDev, conf),
557 DEFINE_PROP_INT32("idx", XenNetDev, dev, -1),
558 };
559
560 static void xen_netdev_class_init(ObjectClass *class, const void *data)
561 {
562 DeviceClass *dev_class = DEVICE_CLASS(class);
563 XenDeviceClass *xendev_class = XEN_DEVICE_CLASS(class);
564
565 xendev_class->backend = "qnic";
566 xendev_class->device = "vif";
567 xendev_class->get_name = xen_netdev_get_name;
568 xendev_class->realize = xen_netdev_realize;
569 xendev_class->frontend_changed = xen_netdev_frontend_changed;
570 xendev_class->unrealize = xen_netdev_unrealize;
571 set_bit(DEVICE_CATEGORY_NETWORK, dev_class->categories);
572 dev_class->user_creatable = true;
573
574 device_class_set_props(dev_class, xen_netdev_properties);
575 }
576
577 static const TypeInfo xen_net_type_info = {
578 .name = TYPE_XEN_NET_DEVICE,
579 .parent = TYPE_XEN_DEVICE,
580 .instance_size = sizeof(XenNetDev),
581 .class_init = xen_netdev_class_init,
582 };
583
584 static void xen_net_register_types(void)
585 {
586 type_register_static(&xen_net_type_info);
587 }
588
589 type_init(xen_net_register_types)
590
591 /* Called to instantiate a XenNetDev when the backend is detected. */
592 static void xen_net_device_create(XenBackendInstance *backend,
593 QDict *opts, Error **errp)
594 {
595 ERRP_GUARD();
596 XenBus *xenbus = xen_backend_get_bus(backend);
597 const char *name = xen_backend_get_name(backend);
598 XenDevice *xendev = NULL;
599 unsigned long number;
600 const char *macstr;
601 XenNetDev *net;
602 MACAddr mac;
603
604 if (qemu_strtoul(name, NULL, 10, &number) || number >= INT_MAX) {
605 error_setg(errp, "failed to parse name '%s'", name);
606 goto fail;
607 }
608
609 trace_xen_netdev_create(number);
610
611 macstr = qdict_get_try_str(opts, "mac");
612 if (macstr == NULL) {
613 error_setg(errp, "no MAC address found");
614 goto fail;
615 }
616
617 if (net_parse_macaddr(mac.a, macstr) < 0) {
618 error_setg(errp, "failed to parse MAC address");
619 goto fail;
620 }
621
622 xendev = XEN_DEVICE(qdev_new(TYPE_XEN_NET_DEVICE));
623 net = XEN_NET_DEVICE(xendev);
624
625 net->dev = number;
626 memcpy(&net->conf.macaddr, &mac, sizeof(mac));
627
628 if (qdev_realize_and_unref(DEVICE(xendev), BUS(xenbus), errp)) {
629 xen_backend_set_device(backend, xendev);
630 return;
631 }
632
633 error_prepend(errp, "realization of net device %lu failed: ",
634 number);
635
636 fail:
637 if (xendev) {
638 object_unparent(OBJECT(xendev));
639 }
640 }
641
642 static void xen_net_device_destroy(XenBackendInstance *backend,
643 Error **errp)
644 {
645 ERRP_GUARD();
646 XenDevice *xendev = xen_backend_get_device(backend);
647 XenNetDev *netdev = XEN_NET_DEVICE(xendev);
648
649 trace_xen_netdev_destroy(netdev->dev);
650
651 object_unparent(OBJECT(xendev));
652 }
653
654 static const XenBackendInfo xen_net_backend_info = {
655 .type = "qnic",
656 .create = xen_net_device_create,
657 .destroy = xen_net_device_destroy,
658 };
659
660 static void xen_net_register_backend(void)
661 {
662 xen_backend_register(&xen_net_backend_info);
663 }
664
665 xen_backend_init(xen_net_register_backend);