mirror of https://gitee.com/openkylin/linux.git
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>
This commit is contained in:
parent
5051654764
commit
bf6d40344d
|
@ -68,7 +68,7 @@ typedef uint8_t u8;
|
||||||
|
|
||||||
/* Use in-kernel ones, which defines VIRTIO_F_VERSION_1 */
|
/* Use in-kernel ones, which defines VIRTIO_F_VERSION_1 */
|
||||||
#include "../../include/uapi/linux/virtio_config.h"
|
#include "../../include/uapi/linux/virtio_config.h"
|
||||||
#include <linux/virtio_net.h>
|
#include "../../include/uapi/linux/virtio_net.h"
|
||||||
#include "../../include/uapi/linux/virtio_blk.h"
|
#include "../../include/uapi/linux/virtio_blk.h"
|
||||||
#include <linux/virtio_console.h>
|
#include <linux/virtio_console.h>
|
||||||
#include <linux/virtio_rng.h>
|
#include <linux/virtio_rng.h>
|
||||||
|
@ -2224,7 +2224,6 @@ static void init_pci_config(struct pci_config *pci, u16 type,
|
||||||
*
|
*
|
||||||
* eg :
|
* eg :
|
||||||
* VIRTIO_ID_CONSOLE: class = 0x07, subclass = 0x00
|
* VIRTIO_ID_CONSOLE: class = 0x07, subclass = 0x00
|
||||||
* VIRTIO_ID_NET: class = 0x02, subclass = 0x00
|
|
||||||
* VIRTIO_ID_RNG: class = 0xff, subclass = 0
|
* VIRTIO_ID_RNG: class = 0xff, subclass = 0
|
||||||
*/
|
*/
|
||||||
pci->class = class;
|
pci->class = class;
|
||||||
|
@ -2485,6 +2484,7 @@ static void configure_device(int fd, const char *tapif, u32 ipaddr)
|
||||||
static int get_tun_device(char tapif[IFNAMSIZ])
|
static int get_tun_device(char tapif[IFNAMSIZ])
|
||||||
{
|
{
|
||||||
struct ifreq ifr;
|
struct ifreq ifr;
|
||||||
|
int vnet_hdr_sz;
|
||||||
int netfd;
|
int netfd;
|
||||||
|
|
||||||
/* Start with this zeroed. Messy but sure. */
|
/* Start with this zeroed. Messy but sure. */
|
||||||
|
@ -2512,6 +2512,18 @@ static int get_tun_device(char tapif[IFNAMSIZ])
|
||||||
*/
|
*/
|
||||||
ioctl(netfd, TUNSETNOCSUM, 1);
|
ioctl(netfd, TUNSETNOCSUM, 1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* In virtio before 1.0 (aka legacy virtio), we added a 16-bit
|
||||||
|
* field at the end of the network header iff
|
||||||
|
* VIRTIO_NET_F_MRG_RXBUF was negotiated. For virtio 1.0,
|
||||||
|
* that became the norm, but we need to tell the tun device
|
||||||
|
* about our expanded header (which is called
|
||||||
|
* virtio_net_hdr_mrg_rxbuf in the legacy system).
|
||||||
|
*/
|
||||||
|
vnet_hdr_sz = sizeof(struct virtio_net_hdr_mrg_rxbuf);
|
||||||
|
if (ioctl(netfd, TUNSETVNETHDRSZ, &vnet_hdr_sz) != 0)
|
||||||
|
err(1, "Setting tun header size to %u", vnet_hdr_sz);
|
||||||
|
|
||||||
memcpy(tapif, ifr.ifr_name, IFNAMSIZ);
|
memcpy(tapif, ifr.ifr_name, IFNAMSIZ);
|
||||||
return netfd;
|
return netfd;
|
||||||
}
|
}
|
||||||
|
@ -2535,12 +2547,12 @@ static void setup_tun_net(char *arg)
|
||||||
net_info->tunfd = get_tun_device(tapif);
|
net_info->tunfd = get_tun_device(tapif);
|
||||||
|
|
||||||
/* First we create a new network device. */
|
/* First we create a new network device. */
|
||||||
dev = new_device("net", VIRTIO_ID_NET);
|
dev = new_pci_device("net", VIRTIO_ID_NET, 0x02, 0x00);
|
||||||
dev->priv = net_info;
|
dev->priv = net_info;
|
||||||
|
|
||||||
/* Network devices need a recv and a send queue, just like console. */
|
/* Network devices need a recv and a send queue, just like console. */
|
||||||
add_virtqueue(dev, VIRTQUEUE_NUM, net_input);
|
add_pci_virtqueue(dev, net_input);
|
||||||
add_virtqueue(dev, VIRTQUEUE_NUM, net_output);
|
add_pci_virtqueue(dev, net_output);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We need a socket to perform the magic network ioctls to bring up the
|
* 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)
|
||||||
p = strchr(arg, ':');
|
p = strchr(arg, ':');
|
||||||
if (p) {
|
if (p) {
|
||||||
str2mac(p+1, conf.mac);
|
str2mac(p+1, conf.mac);
|
||||||
add_feature(dev, VIRTIO_NET_F_MAC);
|
add_pci_feature(dev, VIRTIO_NET_F_MAC);
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2574,25 +2586,21 @@ static void setup_tun_net(char *arg)
|
||||||
configure_device(ipfd, tapif, ip);
|
configure_device(ipfd, tapif, ip);
|
||||||
|
|
||||||
/* Expect Guest to handle everything except UFO */
|
/* Expect Guest to handle everything except UFO */
|
||||||
add_feature(dev, VIRTIO_NET_F_CSUM);
|
add_pci_feature(dev, VIRTIO_NET_F_CSUM);
|
||||||
add_feature(dev, VIRTIO_NET_F_GUEST_CSUM);
|
add_pci_feature(dev, VIRTIO_NET_F_GUEST_CSUM);
|
||||||
add_feature(dev, VIRTIO_NET_F_GUEST_TSO4);
|
add_pci_feature(dev, VIRTIO_NET_F_GUEST_TSO4);
|
||||||
add_feature(dev, VIRTIO_NET_F_GUEST_TSO6);
|
add_pci_feature(dev, VIRTIO_NET_F_GUEST_TSO6);
|
||||||
add_feature(dev, VIRTIO_NET_F_GUEST_ECN);
|
add_pci_feature(dev, VIRTIO_NET_F_GUEST_ECN);
|
||||||
add_feature(dev, VIRTIO_NET_F_HOST_TSO4);
|
add_pci_feature(dev, VIRTIO_NET_F_HOST_TSO4);
|
||||||
add_feature(dev, VIRTIO_NET_F_HOST_TSO6);
|
add_pci_feature(dev, VIRTIO_NET_F_HOST_TSO6);
|
||||||
add_feature(dev, VIRTIO_NET_F_HOST_ECN);
|
add_pci_feature(dev, VIRTIO_NET_F_HOST_ECN);
|
||||||
/* We handle indirect ring entries */
|
/* We handle indirect ring entries */
|
||||||
add_feature(dev, VIRTIO_RING_F_INDIRECT_DESC);
|
add_pci_feature(dev, VIRTIO_RING_F_INDIRECT_DESC);
|
||||||
/* We're compliant with the damn spec. */
|
set_device_config(dev, &conf, sizeof(conf));
|
||||||
add_feature(dev, VIRTIO_F_ANY_LAYOUT);
|
|
||||||
set_config(dev, sizeof(conf), &conf);
|
|
||||||
|
|
||||||
/* We don't need the socket any more; setup is done. */
|
/* We don't need the socket any more; setup is done. */
|
||||||
close(ipfd);
|
close(ipfd);
|
||||||
|
|
||||||
devices.device_num++;
|
|
||||||
|
|
||||||
if (bridging)
|
if (bridging)
|
||||||
verbose("device %u: tun %s attached to bridge: %s\n",
|
verbose("device %u: tun %s attached to bridge: %s\n",
|
||||||
devices.device_num, tapif, arg);
|
devices.device_num, tapif, arg);
|
||||||
|
|
Loading…
Reference in New Issue