diff options
author | Rusty Russell <rusty@rustcorp.com.au> | 2015-02-10 23:46:01 -0500 |
---|---|---|
committer | Rusty Russell <rusty@rustcorp.com.au> | 2015-02-11 01:17:39 -0500 |
commit | bf6d40344d7006f29da1a2782f45188cdbbb0904 (patch) | |
tree | 888df89d98db9d07d6e4d9c90489fc9fda102e26 /tools/lguest/lguest.c | |
parent | 5051654764d55a101747b5b2a695bcecae75fa4c (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.c | 48 |
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) | |||
2485 | static int get_tun_device(char tapif[IFNAMSIZ]) | 2484 | static 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); |