[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PULL 2/3] tap-bsd: implement a FreeBSD only version of tap_open
From: Roger Pau Monne <roger.pau@xxxxxxxxxx> The current behaviour of tap_open for BSD systems differ greatly from it's Linux counterpart. Since FreeBSD supports interface renaming and tap device cloning by opening /dev/tap, implement a FreeBSD specific version of tap_open that behaves like it's Linux counterpart. This is specially important for toolstacks that use Qemu (like Xen libxl), in order to have a unified behaviour across suported platforms. Signed-off-by: Roger Pau Monnà <roger.pau@xxxxxxxxxx> Signed-off-by: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx> Reviewed-by: Stefan Hajnoczi <stefanha@xxxxxxxxxx> --- net/tap-bsd.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 69 insertions(+), 1 deletion(-) 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; -- 1.7.10.4 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |