diff --git a/usr.sbin/bhyve/net_backends.c b/usr.sbin/bhyve/net_backends.c --- a/usr.sbin/bhyve/net_backends.c +++ b/usr.sbin/bhyve/net_backends.c @@ -89,8 +89,9 @@ nvlist_t *nvl __unused, net_be_rxeof_t cb, void *param) { struct tap_priv *priv = NET_BE_PRIV(be); + struct ifreq ifr = {}; char tbuf[80]; - int opt = 1, up = IFF_UP; + int opt = 1, up = IFF_UP, vhdrlen = VNET_HDR_LEN; #ifndef WITHOUT_CAPSICUM cap_rights_t rights; @@ -124,6 +125,17 @@ goto error; } + if (ioctl(be->fd, TAPSVNETHDR, &vhdrlen) == -1) { + EPRINTLN("tap device set virtio-net header length failed"); + goto error; + } + be->be_vnet_hdr_len = vhdrlen; + + be->if_curcap = 0; + if (ioctl(be->fd, SIOCGIFCAP, &ifr) != -1) { + be->if_curcap = ifr.ifr_curcap; + } + #ifndef WITHOUT_CAPSICUM cap_rights_init(&rights, CAP_EVENT, CAP_READ, CAP_WRITE); if (caph_rights_limit(be->fd, &rights) == -1) @@ -230,10 +242,15 @@ } uint64_t -tap_get_cap(struct net_backend *be __unused) +tap_get_cap(struct net_backend *be) { + /* Report checksum offloading feature if the interface supports it */ + if (be->if_curcap & (IFCAP_TXCSUM | IFCAP_TXCSUM_IPV6)) { + return VIRTIO_NET_F_CSUM; + } - return (0); /* no capabilities for now */ + /* no other capabilities returned for now */ + return (0); } int diff --git a/usr.sbin/bhyve/net_backends_priv.h b/usr.sbin/bhyve/net_backends_priv.h --- a/usr.sbin/bhyve/net_backends_priv.h +++ b/usr.sbin/bhyve/net_backends_priv.h @@ -109,6 +109,9 @@ unsigned int be_vnet_hdr_len; unsigned int fe_vnet_hdr_len; + /* tap interface capabilities */ + int if_curcap; + /* Size of backend-specific private data. */ size_t priv_size;