* THE SOFTWARE.
*/
+#include "qemu/osdep.h"
#include "tap_int.h"
#include "tap-linux.h"
#include "net/tap.h"
#include <sys/ioctl.h>
#include "sysemu/sysemu.h"
-#include "qemu-common.h"
+#include "qapi/error.h"
#include "qemu/error-report.h"
+#include "qemu/cutils.h"
#define PATH_NET_TUN "/dev/net/tun"
int tap_open(char *ifname, int ifname_size, int *vnet_hdr,
- int vnet_hdr_required, int mq_required)
+ int vnet_hdr_required, int mq_required, Error **errp)
{
struct ifreq ifr;
int fd, ret;
TFR(fd = open(PATH_NET_TUN, O_RDWR));
if (fd < 0) {
- error_report("could not open %s: %m", PATH_NET_TUN);
+ error_setg_errno(errp, errno, "could not open %s", PATH_NET_TUN);
return -1;
}
memset(&ifr, 0, sizeof(ifr));
}
if (vnet_hdr_required && !*vnet_hdr) {
- error_report("vnet_hdr=1 requested, but no kernel "
- "support for IFF_VNET_HDR available");
+ error_setg(errp, "vnet_hdr=1 requested, but no kernel "
+ "support for IFF_VNET_HDR available");
close(fd);
return -1;
}
if (mq_required) {
if (!(features & IFF_MULTI_QUEUE)) {
- error_report("multiqueue required, but no kernel "
- "support for IFF_MULTI_QUEUE available");
+ error_setg(errp, "multiqueue required, but no kernel "
+ "support for IFF_MULTI_QUEUE available");
close(fd);
return -1;
} else {
ret = ioctl(fd, TUNSETIFF, (void *) &ifr);
if (ret != 0) {
if (ifname[0] != '\0') {
- error_report("could not configure %s (%s): %m", PATH_NET_TUN, ifr.ifr_name);
+ error_setg_errno(errp, errno, "could not configure %s (%s)",
+ PATH_NET_TUN, ifr.ifr_name);
} else {
- error_report("could not configure %s: %m", PATH_NET_TUN);
+ error_setg_errno(errp, errno, "could not configure %s",
+ PATH_NET_TUN);
}
close(fd);
return -1;
*/
#define TAP_DEFAULT_SNDBUF 0
-int tap_set_sndbuf(int fd, const NetdevTapOptions *tap)
+void tap_set_sndbuf(int fd, const NetdevTapOptions *tap, Error **errp)
{
int sndbuf;
}
if (ioctl(fd, TUNSETSNDBUF, &sndbuf) == -1 && tap->has_sndbuf) {
- error_report("TUNSETSNDBUF ioctl failed: %s", strerror(errno));
- return -1;
+ error_setg_errno(errp, errno, "TUNSETSNDBUF ioctl failed");
}
- return 0;
}
int tap_probe_vnet_hdr(int fd)
}
}
+int tap_fd_set_vnet_le(int fd, int is_le)
+{
+ int arg = is_le ? 1 : 0;
+
+ if (!ioctl(fd, TUNSETVNETLE, &arg)) {
+ return 0;
+ }
+
+ /* Check if our kernel supports TUNSETVNETLE */
+ if (errno == EINVAL) {
+ return -errno;
+ }
+
+ error_report("TUNSETVNETLE ioctl() failed: %s.", strerror(errno));
+ abort();
+}
+
+int tap_fd_set_vnet_be(int fd, int is_be)
+{
+ int arg = is_be ? 1 : 0;
+
+ if (!ioctl(fd, TUNSETVNETBE, &arg)) {
+ return 0;
+ }
+
+ /* Check if our kernel supports TUNSETVNETBE */
+ if (errno == EINVAL) {
+ return -errno;
+ }
+
+ error_report("TUNSETVNETBE ioctl() failed: %s.", strerror(errno));
+ abort();
+}
+
void tap_fd_set_offload(int fd, int csum, int tso4,
int tso6, int ecn, int ufo)
{