aboutsummaryrefslogtreecommitdiffstats
path: root/tools/lguest/lguest.c
diff options
context:
space:
mode:
authorRusty Russell <rusty@rustcorp.com.au>2015-02-10 23:46:01 -0500
committerRusty Russell <rusty@rustcorp.com.au>2015-02-11 01:17:39 -0500
commitbf6d40344d7006f29da1a2782f45188cdbbb0904 (patch)
tree888df89d98db9d07d6e4d9c90489fc9fda102e26 /tools/lguest/lguest.c
parent5051654764d55a101747b5b2a695bcecae75fa4c (diff)
lguest: Convert net device to virtio 1.0 PCI.
The only real change here (other than using the PCI bus) is that we didn't negotiate VIRTIO_NET_F_MRG_RXBUF before, so the format of the packet header changed with virtio 1.0; we need TUNSETVNETHDRSZ on the tun fd to tell it about the extra two bytes. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Diffstat (limited to 'tools/lguest/lguest.c')
-rw-r--r--tools/lguest/lguest.c48
1 files changed, 28 insertions, 20 deletions
diff --git a/tools/lguest/lguest.c b/tools/lguest/lguest.c
index d4a79f6ddfbd..b6c88a10a4c9 100644
--- a/tools/lguest/lguest.c
+++ b/tools/lguest/lguest.c
@@ -68,7 +68,7 @@ typedef uint8_t u8;
68 68
69/* Use in-kernel ones, which defines VIRTIO_F_VERSION_1 */ 69/* Use in-kernel ones, which defines VIRTIO_F_VERSION_1 */
70#include "../../include/uapi/linux/virtio_config.h" 70#include "../../include/uapi/linux/virtio_config.h"
71#include <linux/virtio_net.h> 71#include "../../include/uapi/linux/virtio_net.h"
72#include "../../include/uapi/linux/virtio_blk.h" 72#include "../../include/uapi/linux/virtio_blk.h"
73#include <linux/virtio_console.h> 73#include <linux/virtio_console.h>
74#include <linux/virtio_rng.h> 74#include <linux/virtio_rng.h>
@@ -2224,7 +2224,6 @@ static void init_pci_config(struct pci_config *pci, u16 type,
2224 * 2224 *
2225 * eg : 2225 * eg :
2226 * VIRTIO_ID_CONSOLE: class = 0x07, subclass = 0x00 2226 * VIRTIO_ID_CONSOLE: class = 0x07, subclass = 0x00
2227 * VIRTIO_ID_NET: class = 0x02, subclass = 0x00
2228 * VIRTIO_ID_RNG: class = 0xff, subclass = 0 2227 * VIRTIO_ID_RNG: class = 0xff, subclass = 0
2229 */ 2228 */
2230 pci->class = class; 2229 pci->class = class;
@@ -2485,6 +2484,7 @@ static void configure_device(int fd, const char *tapif, u32 ipaddr)
2485static int get_tun_device(char tapif[IFNAMSIZ]) 2484static int get_tun_device(char tapif[IFNAMSIZ])
2486{ 2485{
2487 struct ifreq ifr; 2486 struct ifreq ifr;
2487 int vnet_hdr_sz;
2488 int netfd; 2488 int netfd;
2489 2489
2490 /* Start with this zeroed. Messy but sure. */ 2490 /* Start with this zeroed. Messy but sure. */
@@ -2512,6 +2512,18 @@ static int get_tun_device(char tapif[IFNAMSIZ])
2512 */ 2512 */
2513 ioctl(netfd, TUNSETNOCSUM, 1); 2513 ioctl(netfd, TUNSETNOCSUM, 1);
2514 2514
2515 /*
2516 * In virtio before 1.0 (aka legacy virtio), we added a 16-bit
2517 * field at the end of the network header iff
2518 * VIRTIO_NET_F_MRG_RXBUF was negotiated. For virtio 1.0,
2519 * that became the norm, but we need to tell the tun device
2520 * about our expanded header (which is called
2521 * virtio_net_hdr_mrg_rxbuf in the legacy system).
2522 */
2523 vnet_hdr_sz = sizeof(struct virtio_net_hdr_mrg_rxbuf);
2524 if (ioctl(netfd, TUNSETVNETHDRSZ, &vnet_hdr_sz) != 0)
2525 err(1, "Setting tun header size to %u", vnet_hdr_sz);
2526
2515 memcpy(tapif, ifr.ifr_name, IFNAMSIZ); 2527 memcpy(tapif, ifr.ifr_name, IFNAMSIZ);
2516 return netfd; 2528 return netfd;
2517} 2529}
@@ -2535,12 +2547,12 @@ static void setup_tun_net(char *arg)
2535 net_info->tunfd = get_tun_device(tapif); 2547 net_info->tunfd = get_tun_device(tapif);
2536 2548
2537 /* First we create a new network device. */ 2549 /* First we create a new network device. */
2538 dev = new_device("net", VIRTIO_ID_NET); 2550 dev = new_pci_device("net", VIRTIO_ID_NET, 0x02, 0x00);
2539 dev->priv = net_info; 2551 dev->priv = net_info;
2540 2552
2541 /* Network devices need a recv and a send queue, just like console. */ 2553 /* Network devices need a recv and a send queue, just like console. */
2542 add_virtqueue(dev, VIRTQUEUE_NUM, net_input); 2554 add_pci_virtqueue(dev, net_input);
2543 add_virtqueue(dev, VIRTQUEUE_NUM, net_output); 2555 add_pci_virtqueue(dev, net_output);
2544 2556
2545 /* 2557 /*
2546 * We need a socket to perform the magic network ioctls to bring up the 2558 * We need a socket to perform the magic network ioctls to bring up the
@@ -2560,7 +2572,7 @@ static void setup_tun_net(char *arg)
2560 p = strchr(arg, ':'); 2572 p = strchr(arg, ':');
2561 if (p) { 2573 if (p) {
2562 str2mac(p+1, conf.mac); 2574 str2mac(p+1, conf.mac);
2563 add_feature(dev, VIRTIO_NET_F_MAC); 2575 add_pci_feature(dev, VIRTIO_NET_F_MAC);
2564 *p = '\0'; 2576 *p = '\0';
2565 } 2577 }
2566 2578
@@ -2574,25 +2586,21 @@ static void setup_tun_net(char *arg)
2574 configure_device(ipfd, tapif, ip); 2586 configure_device(ipfd, tapif, ip);
2575 2587
2576 /* Expect Guest to handle everything except UFO */ 2588 /* Expect Guest to handle everything except UFO */
2577 add_feature(dev, VIRTIO_NET_F_CSUM); 2589 add_pci_feature(dev, VIRTIO_NET_F_CSUM);
2578 add_feature(dev, VIRTIO_NET_F_GUEST_CSUM); 2590 add_pci_feature(dev, VIRTIO_NET_F_GUEST_CSUM);
2579 add_feature(dev, VIRTIO_NET_F_GUEST_TSO4); 2591 add_pci_feature(dev, VIRTIO_NET_F_GUEST_TSO4);
2580 add_feature(dev, VIRTIO_NET_F_GUEST_TSO6); 2592 add_pci_feature(dev, VIRTIO_NET_F_GUEST_TSO6);
2581 add_feature(dev, VIRTIO_NET_F_GUEST_ECN); 2593 add_pci_feature(dev, VIRTIO_NET_F_GUEST_ECN);
2582 add_feature(dev, VIRTIO_NET_F_HOST_TSO4); 2594 add_pci_feature(dev, VIRTIO_NET_F_HOST_TSO4);
2583 add_feature(dev, VIRTIO_NET_F_HOST_TSO6); 2595 add_pci_feature(dev, VIRTIO_NET_F_HOST_TSO6);
2584 add_feature(dev, VIRTIO_NET_F_HOST_ECN); 2596 add_pci_feature(dev, VIRTIO_NET_F_HOST_ECN);
2585 /* We handle indirect ring entries */ 2597 /* We handle indirect ring entries */
2586 add_feature(dev, VIRTIO_RING_F_INDIRECT_DESC); 2598 add_pci_feature(dev, VIRTIO_RING_F_INDIRECT_DESC);
2587 /* We're compliant with the damn spec. */ 2599 set_device_config(dev, &conf, sizeof(conf));
2588 add_feature(dev, VIRTIO_F_ANY_LAYOUT);
2589 set_config(dev, sizeof(conf), &conf);
2590 2600
2591 /* We don't need the socket any more; setup is done. */ 2601 /* We don't need the socket any more; setup is done. */
2592 close(ipfd); 2602 close(ipfd);
2593 2603
2594 devices.device_num++;
2595
2596 if (bridging) 2604 if (bridging)
2597 verbose("device %u: tun %s attached to bridge: %s\n", 2605 verbose("device %u: tun %s attached to bridge: %s\n",
2598 devices.device_num, tapif, arg); 2606 devices.device_num, tapif, arg);