From: Daniel Hokka Zakrisson Date: Sat, 1 Mar 2008 00:22:34 +0000 (+0000) Subject: Add basic support for creating tun/tap interfaces in the configuration. X-Git-Tag: release-0.30.215~15 X-Git-Url: http://git.linux-vserver.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f32bc7966248cb1b9f3c535669db577cd022c369;p=util-vserver.git Add basic support for creating tun/tap interfaces in the configuration. git-svn-id: http://svn.linux-vserver.org/svn/util-vserver/trunk@2692 94cd875c-1c1d-0410-91d2-eb244daf1a30 --- diff --git a/doc/configuration.xml b/doc/configuration.xml index 75a7af9..9ce06f0 100644 --- a/doc/configuration.xml +++ b/doc/configuration.xml @@ -1341,6 +1341,47 @@ When this file exists, the steps which setup and destroy a VLAN interface will be executed. + + +When this file exists, a tun interface will be created when the guest +starts, and removed when the guest stops. + + + + +When this file exists, a tap interface will be created when the guest +starts, and removed when the guest stops. + + + + +If a tun or tap interface is created, the presence of this file will +disable checksumming on it. + + + + +When this file exists, the tun/tap interface created will not be +owned by this particular guest. + + + + +Sets the ownership of tun/tap interfaces. Requires a user id, not a +username. + + + + +Sets the group ownership of tun/tap interfaces. Requires a group id, +not a group name. + + + + +Sets the link type of tun/tap interfaces. + + diff --git a/scripts/util-vserver-vars.pathsubst b/scripts/util-vserver-vars.pathsubst index 00a7c42..fc50a56 100644 --- a/scripts/util-vserver-vars.pathsubst +++ b/scripts/util-vserver-vars.pathsubst @@ -70,6 +70,7 @@ _SECURE_MOUNT="$__PKGLIBDIR/secure-mount" _SETATTR="$__SBINDIR/setattr" _SHOWPERM="$__LEGACYDIR/showperm" _START_VSERVERS="$__PKGLIBDIR/start-vservers" +_TUNCTL="$__PKGLIBDIR/tunctl" _VAPT_GET="$__SBINDIR/vapt-get" _VAPT_GET_WORKER="$__PKGLIBDIR/vapt-get-worker" _VATTRIBUTE="$__SBINDIR/vattribute" diff --git a/scripts/vserver.functions b/scripts/vserver.functions index e6482c6..472673a 100644 --- a/scripts/vserver.functions +++ b/scripts/vserver.functions @@ -66,6 +66,7 @@ _IS_FAKEINIT= INITSTYLE=sysv S_CONTEXT= +N_CONTEXT= SILENT_OPT= @@ -108,9 +109,7 @@ function _generateChbindOptions f="$vdir"/interfaces/lback getFileValue lback "$f" - getFileValue nid "$vdir/ncontext" "$vdir/context" - - CHBIND_CMD=( $_CHBIND $SILENT_OPT --secure ${nid:+--nid "$nid"} + CHBIND_CMD=( $_CHBIND $SILENT_OPT --secure ${N_CONTEXT:+--nid "$N_CONTEXT"} ${bcast:+--bcast "$bcast"} ${lback:+--lback "$lback"} ) @@ -512,6 +511,33 @@ create them before starting the vserver and use the 'nodev' flag then" return 0 } +function _getTunInfo +{ + local iface="$1" + + test -e "$iface/tun" -o -e "$iface/tap" || return 1 + test ! -e "$iface/tun" || echo --tun + test ! -e "$iface/tap" || echo --tap + test ! -e "$iface/nocsum" || echo --~checksum + test -e "$iface/shared" || echo --nid-failure-ok "$N_CONTEXT" + if test -e "$iface/uid"; then + local uid + getFileValue uid "$iface/uid" + echo --uid "$uid" + fi + if test -e "$iface/gid"; then + local gid + getFileValue gid "$iface/gid" + echo --gid "$gid" + fi + if test -e "$iface/linktype"; then + local linktype + getFileValue linktype "$iface/linktype" + echo --linktype "$linktype" + fi + return 0 +} + ## Usage: _processSingleInterface function _processSingleInterface { @@ -571,21 +597,27 @@ function _processSingleInterface if ! test -e "$iface"/indirect; then # XXX: IPv6 hack - use_bcast="broadcast ${bcast:-+}" + local use_bcast="broadcast ${bcast:-+}" echo "$ip" | $_GREP -q : && use_bcast= + + local tun_info + if tun_info=$(_getTunInfo "$iface"); then + _addInterfaceCmd TUNCTL "$dev" $tun_info + fi + _addInterfaceCmd IP_ADDR "$ip${prefix:+/$prefix}" $use_bcast ${name:+label "$dev:$name"} dev "$dev" #_addInterfaceCmd IP_ROUTE "$ip${prefix:+/$prefix}" dev "$dev" _addInterfaceCmd IP_LINK "$dev" $up - elif ! test -n "$ctx"; then + elif ! test -n "$N_CONTEXT"; then echo $"Using 'dummy' (indirect) for interface '$dev' requires a fixed context number; dynamic ctx are not supported" >&2 return 1 else - test -z "$mac" || _generateMac mac "$(basename $iface)" "$ctx" || return 1 + test -z "$mac" || _generateMac mac "$(basename $iface)" "$N_CONTEXT" || return 1 _addInterfaceCmd MODPROBE dummy "$dev" _addInterfaceCmd IP_LINK dev dummy0 address "$mac" _addInterfaceCmd NAMEIF "$dev" "$mac" _addInterfaceCmd IP_ADDR "$ip${prefix:+/$prefix}" dev "$dev" - test -z "$extip" || _addInterfaceCmd IPTABLES "$ip${prefix:+/$prefix}" ${name:+label "$dev:$name"} "$ctx" "$extip" + test -z "$extip" || _addInterfaceCmd IPTABLES "$ip${prefix:+/$prefix}" ${name:+label "$dev:$name"} "$N_CONTEXT" "$extip" fi break @@ -596,9 +628,11 @@ function _processSingleInterface function _generateInterfaceOptions { local iface - local ctx - test ! -e "$1"/context || read ctx <"$1"/context + # XXX: This is here instead of in _generateChbindOptions + # to avoid a circular dependency + getFileValue N_CONTEXT "$1/ncontext" "$1/context" + test -n "$N_CONTEXT" -o -z "$S_CONTEXT" || N_CONTEXT="$S_CONTEXT" for iface in "$1/interfaces/"*; do test -d "$iface" || continue @@ -637,6 +671,11 @@ function enableInterfaces IP_ADDR_FLUSH) $_IP addr flush "$@";; IP_LINK) $_IP link set "$@";; IP_ROUTE) $_IP route add "$@";; + TUNCTL) + local dev="$1" + shift + $_TUNCTL --persist "$@" "$dev" + ;; *) echo "Unknown interface-command type '$type'" >&2; false;; esac @@ -672,6 +711,7 @@ function disableInterfaces IP_ADDR_FLUSH) ;; IP_LINK) ;; ## Ignore the link-down command for now IP_ROUTE) $_IP route del "$@";; + TUNCTL) $_TUNCTL --~persist "$1";; *) echo "Unknown interface-command type '$type'" >&2; false;; esac done diff --git a/scripts/vserver.stop b/scripts/vserver.stop index 6b367dd..586adda 100644 --- a/scripts/vserver.stop +++ b/scripts/vserver.stop @@ -95,9 +95,9 @@ fi # Remove persistent so those contexts can be stopped $_VATTRIBUTE --set --xid "$S_CONTEXT" --flag !persistent 2>/dev/null || : -if $_VSERVER_INFO -q "$S_CONTEXT" XIDTYPE static && +if $_VSERVER_INFO -q "$N_CONTEXT" XIDTYPE static && $_VSERVER_INFO - FEATURE vnet; then - $_NATTRIBUTE --set --nid "$S_CONTEXT" --flag !persistent 2>/dev/null || : + $_NATTRIBUTE --set --nid "$N_CONTEXT" --flag !persistent 2>/dev/null || : fi vshelper.doStopSync diff --git a/src/tunctl.c b/src/tunctl.c index 6fe8a81..14b904a 100644 --- a/src/tunctl.c +++ b/src/tunctl.c @@ -61,24 +61,26 @@ #define CMD_LINKTYPE 0x0100 #define CMD_TUN 0x0200 #define CMD_TAP 0x0400 +#define CMD_NID_FAILURE_OK (0x0800 | CMD_NID) int wrapper_exit_code = 255; struct option const CMDLINE_OPTIONS[] = { - { "help", no_argument, 0, CMD_HELP }, - { "version", no_argument, 0, CMD_VERSION }, - { "nid", required_argument, 0, CMD_NID }, - { "device", required_argument, 0, CMD_DEVICE }, - { "persist", no_argument, 0, CMD_PERSIST }, - { "~persist", no_argument, 0, CMD_NOPERSIST }, - { "checksum", no_argument, 0, CMD_CSUM }, - { "~checksum", no_argument, 0, CMD_NOCSUM }, - { "uid", required_argument, 0, CMD_UID }, - { "gid", required_argument, 0, CMD_GID }, - { "linktype", required_argument, 0, CMD_LINKTYPE }, - { "tun", no_argument, 0, CMD_TUN }, - { "tap", no_argument, 0, CMD_TAP }, + { "help", no_argument, 0, CMD_HELP }, + { "version", no_argument, 0, CMD_VERSION }, + { "nid", required_argument, 0, CMD_NID }, + { "device", required_argument, 0, CMD_DEVICE }, + { "persist", no_argument, 0, CMD_PERSIST }, + { "~persist", no_argument, 0, CMD_NOPERSIST }, + { "checksum", no_argument, 0, CMD_CSUM }, + { "~checksum", no_argument, 0, CMD_NOCSUM }, + { "uid", required_argument, 0, CMD_UID }, + { "gid", required_argument, 0, CMD_GID }, + { "linktype", required_argument, 0, CMD_LINKTYPE }, + { "tun", no_argument, 0, CMD_TUN }, + { "tap", no_argument, 0, CMD_TAP }, + { "nid-failure-ok", required_argument, 0, CMD_NID_FAILURE_OK }, {0,0,0,0} }; @@ -140,8 +142,12 @@ doTunctl(struct Arguments *args, char *interface) EioctlD(fd, TUNSETOWNER, (void *) (long) args->uid); if (args->set & CMD_GID) EioctlD(fd, TUNSETGROUP, (void *) (long) args->gid); - if (args->set & CMD_NID) - EioctlD(fd, TUNSETNID, (void *) (long) args->nid); + if (args->set & CMD_NID) { + if (args->set & CMD_NID_FAILURE_OK) + ioctl(fd, TUNSETNID, (void *) (long) args->nid); + else + EioctlD(fd, TUNSETNID, (void *) (long) args->nid); + } if (args->set & CMD_LINKTYPE) EioctlD(fd, TUNSETLINK, (void *) (long) args->linktype); if (args->set & (CMD_PERSIST|CMD_NOPERSIST)) @@ -174,6 +180,7 @@ int main(int argc, char *argv[]) case CMD_HELP : showHelp(1, argv[0], 0); case CMD_VERSION : showVersion(); + case CMD_NID_FAILURE_OK: case CMD_NID : args.nid = Evc_nidopt2nid(optarg, true); break; case CMD_DEVICE : args.device = optarg; break; case CMD_PERSIST : args.persist = 1; break;