diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2014-08-04 11:17:24 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2014-08-04 11:17:24 +0100 |
commit | 7b13ff3f156b98c3183dfa30edfd6473e8660374 (patch) | |
tree | b5ff0ee807688f810025a540129de130c61f2d81 /net/tap-bsd.c | |
parent | c79805802ba0463713c253307d99ebef56436b8c (diff) | |
parent | b33a5bbfbaab6c1ce653a8e3665a18ca67de1456 (diff) | |
download | hqemu-7b13ff3f156b98c3183dfa30edfd6473e8660374.zip hqemu-7b13ff3f156b98c3183dfa30edfd6473e8660374.tar.gz |
Merge remote-tracking branch 'remotes/sstabellini/xen-20140801' into staging
* remotes/sstabellini/xen-20140801:
qemu: support xen hvm direct kernel boot
tap-bsd: implement a FreeBSD only version of tap_open
xen: fix usage of ENODATA
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'net/tap-bsd.c')
-rw-r--r-- | net/tap-bsd.c | 70 |
1 files changed, 69 insertions, 1 deletions
diff --git a/net/tap-bsd.c b/net/tap-bsd.c index 90f8a02..bf91bd0 100644 --- a/net/tap-bsd.c +++ b/net/tap-bsd.c @@ -27,12 +27,13 @@ #include "sysemu/sysemu.h" #include "qemu/error-report.h" -#ifdef __NetBSD__ +#if defined(__NetBSD__) || defined(__FreeBSD__) #include <sys/ioctl.h> #include <net/if.h> #include <net/if_tap.h> #endif +#ifndef __FreeBSD__ int tap_open(char *ifname, int ifname_size, int *vnet_hdr, int vnet_hdr_required, int mq_required) { @@ -108,6 +109,73 @@ int tap_open(char *ifname, int ifname_size, int *vnet_hdr, return fd; } +#else /* __FreeBSD__ */ + +#define PATH_NET_TAP "/dev/tap" + +int tap_open(char *ifname, int ifname_size, int *vnet_hdr, + int vnet_hdr_required, int mq_required) +{ + int fd, s, ret; + struct ifreq ifr; + + TFR(fd = open(PATH_NET_TAP, O_RDWR)); + if (fd < 0) { + error_report("could not open %s: %s", PATH_NET_TAP, strerror(errno)); + return -1; + } + + memset(&ifr, 0, sizeof(ifr)); + + ret = ioctl(fd, TAPGIFNAME, (void *)&ifr); + if (ret < 0) { + error_report("could not get tap interface name"); + goto error; + } + + if (ifname[0] != '\0') { + /* User requested the interface to have a specific name */ + s = socket(AF_LOCAL, SOCK_DGRAM, 0); + if (s < 0) { + error_report("could not open socket to set interface name"); + goto error; + } + ifr.ifr_data = ifname; + ret = ioctl(s, SIOCSIFNAME, (void *)&ifr); + close(s); + if (ret < 0) { + error_report("could not set tap interface name"); + goto error; + } + } else { + pstrcpy(ifname, ifname_size, ifr.ifr_name); + } + + if (*vnet_hdr) { + /* BSD doesn't have IFF_VNET_HDR */ + *vnet_hdr = 0; + + if (vnet_hdr_required && !*vnet_hdr) { + error_report("vnet_hdr=1 requested, but no kernel " + "support for IFF_VNET_HDR available"); + goto error; + } + } + if (mq_required) { + error_report("mq_required requested, but not kernel support" + "for IFF_MULTI_QUEUE available"); + goto error; + } + + fcntl(fd, F_SETFL, O_NONBLOCK); + return fd; + +error: + close(fd); + return -1; +} +#endif /* __FreeBSD__ */ + int tap_set_sndbuf(int fd, const NetdevTapOptions *tap) { return 0; |