Date: Wed, 15 Feb 2012 18:50:49 +0700 (NOVT) From: Eugene Grosbein <eugen@grosbein.net> To: FreeBSD-gnats-submit@FreeBSD.org Subject: kern/165174: [patch] [tap] allow tap(4) to keep its address on close Message-ID: <201202151150.q1FBon3U006603@eg.sd.rdtc.ru> Resent-Message-ID: <201202151200.q1FC0Lin010013@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 165174 >Category: kern >Synopsis: [patch] [tap] allow tap(4) to keep its address on close >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: change-request >Submitter-Id: current-users >Arrival-Date: Wed Feb 15 12:00:20 UTC 2012 >Closed-Date: >Last-Modified: >Originator: Eugene Grosbein >Release: FreeBSD 8.2-STABLE i386 >Organization: RDTC JSC >Environment: System: FreeBSD eg.sd.rdtc.ru 8.2-STABLE FreeBSD 8.2-STABLE #37: Wed Feb 15 14:22:03 NOVT 2012 root@eg.sd.rdtc.ru:/usr/local/obj/usr/local/src/sys/EG i386 >Description: I routinely start, run and close several VirtualBox-controlled virtual machines within FreeBSD. These machines use tap(4)-based networking. tap interfaces are configured in /etc/rc.conf just like all other interfaces: cloned_interfaces="tap0 tap1 tap2" ifconfig_tap0="inet 192.168.254.1/29" ifconfig_tap1="inet 192.168.254.17/28" ifconfig_tap2="inet 192.168.254.9/29" Each machine uses its own tapX. VirtualBox runs as non-root user with help of /etc/sysctl.conf: net.link.tap.user_open=1 net.link.tap.up_on_open=1 This works for first start of each VM only as tap(4) driver removes interface addresses of tapX on close. Very inconvinient. >How-To-Repeat: Create tap0 with ifconfig, run an application working with tap0, restart the application and its networking fails. >Fix: The following patch introduces new per-interface sysctls that may be used to keep addresses of tap interfaces and interfaces itself up on close: net.link.tap.0.keep_up=1 net.link.tap.1.keep_up=1 net.link.tap.2.keep_up=1 Default value is 0 and corresponds to current behaviour. The patch updates manual page too. --- sys/net/if_tapvar.h.orig 2012-02-15 13:35:31.000000000 +0700 +++ sys/net/if_tapvar.h 2012-02-15 14:06:40.000000000 +0700 @@ -41,6 +41,8 @@ #ifndef _NET_IF_TAPVAR_H_ #define _NET_IF_TAPVAR_H_ +#include <sys/sysctl.h> + /* * tap_mtx locks tap_flags, tap_pid. tap_next locked with global tapmtx. * Other fields locked by owning subsystems. @@ -64,6 +66,9 @@ struct tap_softc { SLIST_ENTRY(tap_softc) tap_next; /* next device in chain */ struct cdev *tap_dev; struct mtx tap_mtx; /* per-softc mutex */ + + struct sysctl_ctx_list ctx; /* sysctl variables */ + int keep_up; }; #endif /* !_NET_IF_TAPVAR_H_ */ --- sys/net/if_tap.c.orig 2012-02-15 13:24:10.000000000 +0700 +++ sys/net/if_tap.c 2012-02-15 16:28:15.000000000 +0700 @@ -229,6 +229,7 @@ tap_clone_destroy(struct ifnet *ifp) { struct tap_softc *tp = ifp->if_softc; + sysctl_ctx_free(&tp->ctx); mtx_lock(&tapmtx); SLIST_REMOVE(&taphead, tp, tap_softc, tap_next); mtx_unlock(&tapmtx); @@ -399,6 +400,8 @@ tapcreate(struct cdev *dev) int unit; char *name = NULL; u_char eaddr[6]; + char num[14]; /* sufficient for 32 bits */ + struct sysctl_oid *oid; dev->si_flags &= ~SI_CHEAPCLONE; @@ -433,6 +436,16 @@ tapcreate(struct cdev *dev) ifp = tp->tap_ifp = if_alloc(IFT_ETHER); if (ifp == NULL) panic("%s%d: can not if_alloc()", name, unit); + + sysctl_ctx_init(&tp->ctx); + snprintf(num, sizeof(num), "%u", unit); + tp->keep_up = 0; + oid = SYSCTL_ADD_NODE(&tp->ctx, &SYSCTL_NODE_CHILDREN(_net_link, tap), + OID_AUTO, num, CTLFLAG_RD, NULL, ""); + SYSCTL_ADD_INT(&tp->ctx, SYSCTL_CHILDREN(oid), OID_AUTO, + "keep_up", CTLTYPE_INT|CTLFLAG_RW, &tp->keep_up, tp->keep_up, + "Keep interface up on close"); + ifp->if_softc = tp; if_initname(ifp, name, unit); ifp->if_init = tapifinit; @@ -528,7 +541,8 @@ tapclose(struct cdev *dev, int foo, int * interface, if we are in VMnet mode. just close the device. */ - if (((tp->tap_flags & TAP_VMNET) == 0) && (ifp->if_flags & IFF_UP)) { + if (!tp->keep_up && + ((tp->tap_flags & TAP_VMNET) == 0) && (ifp->if_flags & IFF_UP)) { mtx_unlock(&tp->tap_mtx); if_down(ifp); mtx_lock(&tp->tap_mtx); --- share/man/man4/tap.4.orig 2012-02-15 14:37:59.000000000 +0700 +++ share/man/man4/tap.4 2012-02-15 16:25:50.000000000 +0700 @@ -268,7 +268,9 @@ .Dq ifconfig tap Ns Sy N No down ) unless the device is a .Em VMnet -device. +device (but see +.Sx SYSCTL VARIABLES +section below). All queued frames are thrown away. If the interface is up when the data device is not open, output frames are thrown away rather than @@ -316,6 +318,14 @@ VMware .Dv SIOCSIFFLAGS . .El +.Sh SYSCTL VARIABLES +In addition to global sysctl variables described above, there are +per-interface variables: +.Bl -tag -width indent +.It Va net.link.tap.X.keep_up: No 0 +Set this variable to 1 and interface tapX will stay up +and keep its address on close regardless of mode. +.El .Sh SEE ALSO .Xr inet 4 , .Xr intro 4 >Release-Note: >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201202151150.q1FBon3U006603>