Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F151509752
D21315.id.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
D21315.id.diff
View Options
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
@@ -158,14 +159,97 @@
#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)
{
@@ -196,6 +280,11 @@
return (-1);
}
+ if (strlcpy(priv->ifname, devname, sizeof(priv->ifname)) >=
+ sizeof(priv->ifname)) {
+ WPRINTF(("TAP device name too long\n"));
+ return (-1);
+ }
strcpy(tbuf, "/dev/");
strlcat(tbuf, devname, sizeof(tbuf));
@@ -215,7 +304,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
@@ -278,16 +367,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;
- return ((features || vnet_hdr_len) ? -1 : 0);
+ ret = tap_set_vnet_hdr_len(be, vnet_hdr_len);
+ assert(ret == 0);
+
+ be->be_vnet_hdr_len = vnet_hdr_len;
+
+ return 0;
}
static struct net_backend tap_backend = {
@@ -324,13 +432,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;
@@ -415,8 +516,11 @@
{
struct netmap_priv *priv = (struct netmap_priv *)be->opaque;
- strlcpy(priv->ifname, devname, sizeof(priv->ifname));
- priv->ifname[sizeof(priv->ifname) - 1] = '\0';
+ if (strlcpy(priv->ifname, devname, sizeof(priv->ifname)) >=
+ sizeof(priv->ifname)) {
+ WPRINTF(("netmap interface name too long\n"));
+ return (-1);
+ }
priv->nmd = nm_open(priv->ifname, NULL, NETMAP_NO_TX_POLL, NULL);
if (priv->nmd == NULL) {
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Apr 9, 10:20 PM (15 h, 39 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31174058
Default Alt Text
D21315.id.diff (4 KB)
Attached To
Mode
D21315: bhyve: tap: add support for offloads
Attached
Detach File
Event Timeline
Log In to Comment