aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr.sbin/bhyve/net_backends.c51
1 files changed, 51 insertions, 0 deletions
diff --git a/usr.sbin/bhyve/net_backends.c b/usr.sbin/bhyve/net_backends.c
index 30c26aea458b..cb1730fc77df 100644
--- a/usr.sbin/bhyve/net_backends.c
+++ b/usr.sbin/bhyve/net_backends.c
@@ -46,6 +46,9 @@ __FBSDID("$FreeBSD$");
#include <sys/uio.h>
#include <net/if.h>
+#if defined(INET6) || defined(INET)
+#include <net/if_tap.h>
+#endif
#include <net/netmap.h>
#include <net/netmap_virt.h>
#define NETMAP_WITH_LIBS
@@ -179,6 +182,17 @@ SET_DECLARE(net_backend_set, struct net_backend);
* The tap backend
*/
+#if defined(INET6) || defined(INET)
+const int pf_list[] = {
+#if defined(INET6)
+ PF_INET6,
+#endif
+#if defined(INET)
+ PF_INET,
+#endif
+};
+#endif
+
struct tap_priv {
struct mevent *mevp;
/*
@@ -211,6 +225,10 @@ tap_init(struct net_backend *be, const char *devname,
struct tap_priv *priv = (struct tap_priv *)be->opaque;
char tbuf[80];
int opt = 1;
+#if defined(INET6) || defined(INET)
+ struct ifreq ifrq;
+ int i, s;
+#endif
#ifndef WITHOUT_CAPSICUM
cap_rights_t rights;
#endif
@@ -238,6 +256,39 @@ tap_init(struct net_backend *be, const char *devname,
goto error;
}
+#if defined(INET6) || defined(INET)
+ /*
+ * Try to UP the interface rather than relying on
+ * net.link.tap.up_on_open.
+ */
+ bzero(&ifrq, sizeof(ifrq));
+ if (ioctl(be->fd, TAPGIFNAME, &ifrq) < 0) {
+ WPRINTF(("Could not get interface name"));
+ goto error;
+ }
+
+ s = -1;
+ for (i = 0; s == -1 && i < nitems(pf_list); i++)
+ s = socket(pf_list[i], SOCK_DGRAM, 0);
+ if (s == -1) {
+ WPRINTF(("Could open socket"));
+ goto error;
+ }
+
+ if (ioctl(s, SIOCGIFFLAGS, &ifrq) < 0) {
+ (void)close(s);
+ WPRINTF(("Could not get interface flags"));
+ goto error;
+ }
+ ifrq.ifr_flags |= IFF_UP;
+ if (ioctl(s, SIOCSIFFLAGS, &ifrq) < 0) {
+ (void)close(s);
+ WPRINTF(("Could not set interface flags"));
+ goto error;
+ }
+ (void)close(s);
+#endif
+
#ifndef WITHOUT_CAPSICUM
cap_rights_init(&rights, CAP_EVENT, CAP_READ, CAP_WRITE);
if (caph_rights_limit(be->fd, &rights) == -1)