interface will be executed.
</description>
</boolean>
+ <boolean name="tun" since="0.30.215">
+ <description>
+When this file exists, a tun interface will be created when the guest
+starts, and removed when the guest stops.
+ </description>
+ </boolean>
+ <boolean name="tap" since="0.30.215">
+ <description>
+When this file exists, a tap interface will be created when the guest
+starts, and removed when the guest stops.
+ </description>
+ </boolean>
+ <boolean name="nocsum" since="0.30.215">
+ <description>
+If a tun or tap interface is created, the presence of this file will
+disable checksumming on it.
+ </description>
+ </boolean>
+ <boolean name="shared" since="0.30.215">
+ <description>
+When this file exists, the tun/tap interface created will not be
+owned by this particular guest.
+ </description>
+ </boolean>
+ <scalar name="uid" since="0.30.215">
+ <description>
+Sets the ownership of tun/tap interfaces. Requires a user id, not a
+username.
+ </description>
+ </scalar>
+ <scalar name="gid" since="0.30.215">
+ <description>
+Sets the group ownership of tun/tap interfaces. Requires a group id,
+not a group name.
+ </description>
+ </scalar>
+ <scalar name="linktype" since="0.30.215">
+ <description>
+Sets the link type of tun/tap interfaces.
+ </description>
+ </scalar>
</collection>
</collection>
INITSTYLE=sysv
S_CONTEXT=
+N_CONTEXT=
SILENT_OPT=
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"}
)
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 <interface-directory>
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
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
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
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
#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}
};
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))
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;