Page MenuHomeFreeBSD

D21315.1776880276.diff
No OneTemporary

Size
4 KB
Referenced Files
None
Subscribers
None

D21315.1776880276.diff

Index: usr.sbin/bhyve/net_backends.c
===================================================================
--- usr.sbin/bhyve/net_backends.c
+++ usr.sbin/bhyve/net_backends.c
@@ -46,6 +46,7 @@
#include <sys/uio.h>
#include <net/if.h>
+#include <net/if_tap.h>
#include <net/netmap.h>
#include <net/netmap_virt.h>
#define NETMAP_WITH_LIBS
@@ -157,19 +158,98 @@
#define WPRINTF(params) printf params
+/*
+ * The virtio-net features supported by the tap and netmap
+ * backends.
+ */
+#define NETMAP_FEATURES (VIRTIO_NET_F_CSUM | VIRTIO_NET_F_HOST_TSO4 | \
+ VIRTIO_NET_F_HOST_TSO6 | VIRTIO_NET_F_HOST_UFO | \
+ VIRTIO_NET_F_GUEST_CSUM | VIRTIO_NET_F_GUEST_TSO4 | \
+ VIRTIO_NET_F_GUEST_TSO6 | VIRTIO_NET_F_GUEST_UFO | \
+ VIRTIO_NET_F_MRG_RXBUF)
+#define TAP_FEATURES NETMAP_FEATURES
+
/*
* The tap backend
*/
struct tap_priv {
+ char ifname[IFNAMSIZ];
struct mevent *mevp;
};
+#define TAP_VHDR_IFCAPS (IFCAP_HWCSUM | IFCAP_HWCSUM_IPV6 \
+ | IFCAP_VLAN_HWCSUM | IFCAP_TSO \
+ | IFCAP_LRO | IFCAP_VLAN_HWTSO)
+
+static int
+tap_set_vnet_hdr_len(struct net_backend *be, unsigned vnet_hdr_len)
+{
+ struct tap_priv *priv = (struct tap_priv *)be->opaque;
+ int ival = vnet_hdr_len;
+ struct ifreq ifreq;
+ int ret;
+ int s;
+
+ /* Configure the virtio-net header length, using the tap(4) character
+ * device interface. */
+ ret = ioctl(be->fd, TAPSVNETHDR, &ival);
+ if (ret) {
+ WPRINTF(("ioctl(TAPSVNETHDR) failed: %s\n",
+ strerror(errno)));
+ return (ret);
+ }
+
+ /* Open a socket to run ioctl() commands on the tap(4) network
+ * interface. */
+ s = socket(AF_LOCAL, SOCK_DGRAM, 0);
+ if (s < 0) {
+ WPRINTF(("socket(AF_LOCAL) failed: %s\n", strerror(errno)));
+ return (s);
+ }
+
+ /* Get interface capabilities: enabled capabilities are stored
+ * in ifreq.ifr_curcap, while supported ones are stored in
+ * ifreq.ifr_reqcap. */
+ memset(&ifreq, 0, sizeof(ifreq));
+ strlcpy(ifreq.ifr_name, priv->ifname, sizeof(ifreq.ifr_name));
+
+ ret = ioctl(s, SIOCGIFCAP, &ifreq);
+ if (ret) {
+ WPRINTF(("ioctl(SIOCGIFCAP) failed: %s\n", strerror(errno)));
+ close(s);
+ return (ret);
+ }
+
+ /* Enable or disable tap(4) capabilities for TX/RX checksum and
+ * TSO/LRO. */
+ if (vnet_hdr_len != 0) {
+ assert((ifreq.ifr_reqcap & TAP_VHDR_IFCAPS) == TAP_VHDR_IFCAPS);
+ ifreq.ifr_reqcap = ifreq.ifr_curcap | TAP_VHDR_IFCAPS;
+ } else {
+ ifreq.ifr_reqcap = ifreq.ifr_curcap & (~TAP_VHDR_IFCAPS);
+ }
+ ret = ioctl(s, SIOCSIFCAP, &ifreq);
+ if (ret) {
+ WPRINTF(("ioctl(SIOCSIFCAP) failed: %s\n", strerror(errno)));
+ close(s);
+ return (ret);
+ }
+
+ close(s);
+
+ return (0);
+}
+
static void
tap_cleanup(struct net_backend *be)
{
struct tap_priv *priv = (struct tap_priv *)be->opaque;
+ /* Remove the virtio-net header length, so that legacy
+ * users can reuse this tap(4). */
+ tap_set_vnet_hdr_len(be, /*vnet_hdr_len=*/0);
+
if (priv->mevp) {
mevent_delete(priv->mevp);
}
@@ -195,6 +275,12 @@
return (-1);
}
+ if (strlen(devname) >= IFNAMSIZ) {
+ WPRINTF(("TAP device name too long\n"));
+ return (-1);
+ }
+
+ strlcpy(priv->ifname, devname, sizeof(priv->ifname));
strcpy(tbuf, "/dev/");
strlcat(tbuf, devname, sizeof(tbuf));
@@ -214,7 +300,7 @@
}
#ifndef WITHOUT_CAPSICUM
- cap_rights_init(&rights, CAP_EVENT, CAP_READ, CAP_WRITE);
+ cap_rights_init(&rights, CAP_EVENT, CAP_READ, CAP_WRITE, CAP_IOCTL);
if (caph_rights_limit(be->fd, &rights) == -1)
errx(EX_OSERR, "Unable to apply rights for sandbox");
#endif
@@ -273,16 +359,35 @@
static uint64_t
tap_get_cap(struct net_backend *be)
{
+ int ret;
- return (0); /* no capabilities for now */
+ /*
+ * Check if we are able to set the virtio net header.
+ * If we are not, we tell the caller that we do not support
+ * any offload.
+ */
+ if (tap_set_vnet_hdr_len(be, sizeof(struct virtio_net_rxhdr))) {
+ return (0);
+ }
+
+ ret = tap_set_vnet_hdr_len(be, 0);
+ assert(ret == 0);
+
+ return (TAP_FEATURES);
}
static int
tap_set_cap(struct net_backend *be, uint64_t features,
unsigned vnet_hdr_len)
{
+ int ret;
+
+ ret = tap_set_vnet_hdr_len(be, vnet_hdr_len);
+ assert(ret == 0);
+
+ be->be_vnet_hdr_len = vnet_hdr_len;
- return ((features || vnet_hdr_len) ? -1 : 0);
+ return 0;
}
static struct net_backend tap_backend = {
@@ -317,13 +422,6 @@
* The netmap backend
*/
-/* The virtio-net features supported by netmap. */
-#define NETMAP_FEATURES (VIRTIO_NET_F_CSUM | VIRTIO_NET_F_HOST_TSO4 | \
- VIRTIO_NET_F_HOST_TSO6 | VIRTIO_NET_F_HOST_UFO | \
- VIRTIO_NET_F_GUEST_CSUM | VIRTIO_NET_F_GUEST_TSO4 | \
- VIRTIO_NET_F_GUEST_TSO6 | VIRTIO_NET_F_GUEST_UFO | \
- VIRTIO_NET_F_MRG_RXBUF)
-
struct netmap_priv {
char ifname[IFNAMSIZ];
struct nm_desc *nmd;

File Metadata

Mime Type
text/plain
Expires
Wed, Apr 22, 5:51 PM (10 h, 21 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28409672
Default Alt Text
D21315.1776880276.diff (4 KB)

Event Timeline