From owner-freebsd-bugs@FreeBSD.ORG Wed Feb 15 12:00:22 2012 Return-Path: Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 01C9610656D9 for ; Wed, 15 Feb 2012 12:00:22 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id CC1E08FC16 for ; Wed, 15 Feb 2012 12:00:21 +0000 (UTC) Received: from freefall.freebsd.org (localhost [127.0.0.1]) by freefall.freebsd.org (8.14.5/8.14.5) with ESMTP id q1FC0Lxd010014 for ; Wed, 15 Feb 2012 12:00:21 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.5/8.14.5/Submit) id q1FC0Lin010013; Wed, 15 Feb 2012 12:00:21 GMT (envelope-from gnats) Resent-Date: Wed, 15 Feb 2012 12:00:21 GMT Resent-Message-Id: <201202151200.q1FC0Lin010013@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Eugene Grosbein Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id DBFDE1065675 for ; Wed, 15 Feb 2012 11:50:53 +0000 (UTC) (envelope-from eugen@eg.sd.rdtc.ru) Received: from eg.sd.rdtc.ru (eg.sd.rdtc.ru [IPv6:2a03:3100:c:13::5]) by mx1.freebsd.org (Postfix) with ESMTP id 0B8348FC23 for ; Wed, 15 Feb 2012 11:50:52 +0000 (UTC) Received: from eg.sd.rdtc.ru (localhost [127.0.0.1]) by eg.sd.rdtc.ru (8.14.5/8.14.5) with ESMTP id q1FBon2B006604 for ; Wed, 15 Feb 2012 18:50:49 +0700 (NOVT) (envelope-from eugen@eg.sd.rdtc.ru) Received: (from eugen@localhost) by eg.sd.rdtc.ru (8.14.5/8.14.5/Submit) id q1FBon3U006603; Wed, 15 Feb 2012 18:50:49 +0700 (NOVT) (envelope-from eugen) Message-Id: <201202151150.q1FBon3U006603@eg.sd.rdtc.ru> Date: Wed, 15 Feb 2012 18:50:49 +0700 (NOVT) From: Eugene Grosbein To: FreeBSD-gnats-submit@FreeBSD.org X-Send-Pr-Version: 3.113 Cc: Subject: kern/165174: [patch] [tap] allow tap(4) to keep its address on close X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 15 Feb 2012 12:00:22 -0000 >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 + /* * 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: