From a6be71d3e49f0f633705ba5e4e08cc1cac811344 Mon Sep 17 00:00:00 2001 From: Daniel Hokka Zakrisson Date: Wed, 8 Aug 2007 20:05:26 +0000 Subject: [PATCH] Add support for the various new APIs in 2.2 and 2.3, in particular, netv2. git-svn-id: http://svn.linux-vserver.org/svn/util-vserver/trunk@2578 94cd875c-1c1d-0410-91d2-eb244daf1a30 --- AUTHORS | 1 + configure.ac | 14 ++-- ensc_wrappers/wrappers-vserver.hc | 4 +- kernel/inode_cmd.h | 14 ++-- kernel/network.h | 32 +++++---- kernel/network_cmd.h | 56 +++++++++++++-- lib/Makefile-files | 14 +++- lib/syscall_ctxcreate-v13.hc | 7 +- lib/syscall_ctxcreate-v21.hc | 46 +++++++++++++ lib/syscall_ctxcreate.c | 17 +++-- lib/syscall_fgetiattr-v22.hc | 44 ++++++++++++ lib/syscall_fgetiattr.c | 38 +++++++++++ lib/syscall_fsetiattr-v22.hc | 34 +++++++++ lib/syscall_fsetiattr.c | 38 +++++++++++ lib/syscall_netadd-net.hc | 28 +++++--- lib/syscall_netadd-netv2.hc | 52 ++++++++++++++ lib/syscall_netadd.c | 19 ++++-- lib/syscall_netremove-net.hc | 32 ++++++--- lib/syscall_netremove-netv2.hc | 65 ++++++++++++++++++ lib/syscall_netremove.c | 19 ++++-- lib/syscall_setsched-v22.hc | 43 ++++++++++++ lib/syscall_setsched.c | 7 +- lib/vserver-internal.h | 40 +++++------ lib/vserver.h | 58 ++++++++++++---- lib_internal/sys_unshare.h | 43 ++++++++++++ src/chbind.c | 69 +------------------ src/naddress.c | 140 ++++++++++++++++++++++++++++---------- src/rpm-fake.c | 2 +- src/vcontext.c | 2 +- vserver-start/main.c | 2 +- 30 files changed, 777 insertions(+), 203 deletions(-) create mode 100644 lib/syscall_ctxcreate-v21.hc create mode 100644 lib/syscall_fgetiattr-v22.hc create mode 100644 lib/syscall_fgetiattr.c create mode 100644 lib/syscall_fsetiattr-v22.hc create mode 100644 lib/syscall_fsetiattr.c create mode 100644 lib/syscall_netadd-netv2.hc create mode 100644 lib/syscall_netremove-netv2.hc create mode 100644 lib/syscall_setsched-v22.hc create mode 100644 lib_internal/sys_unshare.h diff --git a/AUTHORS b/AUTHORS index db53813..7041e8c 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1 +1,2 @@ Enrico Scholz +Daniel Hokka Zakrisson diff --git a/configure.ac b/configure.ac index f72d67d..5caea3a 100644 --- a/configure.ac +++ b/configure.ac @@ -226,18 +226,21 @@ AH_TEMPLATE(VC_ENABLE_API_V13OBS, [Enable support for some obsoleted API of vs AH_TEMPLATE(VC_ENABLE_API_V13, [Enable support for API of vserver 1.3.x]) AH_TEMPLATE(VC_ENABLE_API_NET, [Enable support for network context API]) AH_TEMPLATE(VC_ENABLE_API_V21, [Enable support for API of vserver 2.1.x]) +AH_TEMPLATE(VC_ENABLE_API_V22, [Enable support for API of vserver 2.2.x]) +AH_TEMPLATE(VC_ENABLE_API_V23, [Enable support for API of vserver 2.3.x]) +AH_TEMPLATE(VC_ENABLE_API_NETV2, [Enable support for new networking API]) AH_TEMPLATE(VC_ENABLE_API_OLDPROC, [Enable API for a backward compatible /proc parsing]) AH_TEMPLATE(VC_ENABLE_API_OLDUTS, [Enable API for a backward compatible uts handling]) AC_MSG_CHECKING([for supported APIs]) AC_ARG_ENABLE([apis], [AC_HELP_STRING([--enable-apis=APIS], - [enable support for the given apis; possible values are: legacy,compat,v11,fscompat,v13obs,v13,net, ALL,NOLEGACY (default: v13,net,v21)])], + [enable support for the given apis; possible values are: legacy,compat,v11,fscompat,v13obs,v13,net,v21,v22,v23,netv2 ALL,NOLEGACY (default: v13,net,v21,v22,v23,netv2)])], [], - [enable_apis=v13,net,v21]) + [enable_apis=v13,net,v21,v22,v23,netv2]) -test x"$enable_apis" != xALL || enable_apis='legacy,compat,v11,fscompat,v13obs,v13,net,v21' -test x"$enable_apis" != xNOLEGACY || enable_apis='compat,v11,fscompat,v13,net,v21' +test x"$enable_apis" != xALL || enable_apis='legacy,compat,v11,fscompat,v13obs,v13,net,v21,v22,v23,netv2' +test x"$enable_apis" != xNOLEGACY || enable_apis='compat,v11,fscompat,v13,net,v21,v22,v23,netv2' enable_api_oldproc= enable_api_olduts= old_IFS=$IFS @@ -263,6 +266,9 @@ for i in $enable_apis; do (v13) AC_DEFINE(VC_ENABLE_API_V13, 1);; (net) AC_DEFINE(VC_ENABLE_API_NET, 1);; (v21) AC_DEFINE(VC_ENABLE_API_V21, 1);; + (v22) AC_DEFINE(VC_ENABLE_API_V22, 1);; + (v23) AC_DEFINE(VC_ENABLE_API_V23, 1);; + (netv2) AC_DEFINE(VC_ENABLE_API_NETV2, 1);; (oldproc) enable_api_oldproc=2;; (olduts) enable_api_olduts=2;; (*) AC_MSG_ERROR(['$i' is not a supported API]);; diff --git a/ensc_wrappers/wrappers-vserver.hc b/ensc_wrappers/wrappers-vserver.hc index 6d1047e..a1e1e0a 100644 --- a/ensc_wrappers/wrappers-vserver.hc +++ b/ensc_wrappers/wrappers-vserver.hc @@ -49,9 +49,9 @@ Evc_get_task_nid(pid_t pid) } inline static WRAPPER_DECL xid_t -Evc_ctx_create(xid_t xid) +Evc_ctx_create(xid_t xid, struct vc_ctx_flags *flags) { - register xid_t res = vc_ctx_create(xid); + register xid_t res = vc_ctx_create(xid, flags); FatalErrnoError(res==VC_NOCTX, "vc_ctx_create()"); return res; } diff --git a/kernel/inode_cmd.h b/kernel/inode_cmd.h index ed26aa1..39a825a 100644 --- a/kernel/inode_cmd.h +++ b/kernel/inode_cmd.h @@ -4,22 +4,20 @@ /* inode vserver commands */ -#define VCMD_get_iattr_v0 VC_CMD(INODE, 1, 0) -#define VCMD_set_iattr_v0 VC_CMD(INODE, 2, 0) - #define VCMD_get_iattr VC_CMD(INODE, 1, 1) #define VCMD_set_iattr VC_CMD(INODE, 2, 1) -struct vcmd_ctx_iattr_v0 { - /* device handle in id */ - uint64_t ino; +#define VCMD_fget_iattr VC_CMD(INODE, 3, 0) +#define VCMD_fset_iattr VC_CMD(INODE, 4, 0) + +struct vcmd_ctx_iattr_v1 { + const char *name; uint32_t xid; uint32_t flags; uint32_t mask; }; -struct vcmd_ctx_iattr_v1 { - const char *name; +struct vcmd_ctx_fiattr_v0 { uint32_t xid; uint32_t flags; uint32_t mask; diff --git a/kernel/network.h b/kernel/network.h index 2b84f07..c3b0323 100644 --- a/kernel/network.h +++ b/kernel/network.h @@ -6,34 +6,42 @@ #define MAX_N_CONTEXT 65535 /* Arbitrary limit */ -#define NX_DYNAMIC_ID ((uint32_t)-1) /* id for dynamic context */ - #define NB_IPV4ROOT 16 /* network flags */ -#define NXF_INFO_LOCK 0x00000001 +#define NXF_INFO_PRIVATE 0x00000008 + +#define NXF_SINGLE_IP 0x00000100 -#define NXF_STATE_SETUP (1ULL<<32) -#define NXF_STATE_ADMIN (1ULL<<34) +#define NXF_HIDE_NETIF 0x02000000 -#define NXF_SC_HELPER (1ULL<<36) -#define NXF_PERSISTENT (1ULL<<38) +#define NXF_STATE_SETUP (1ULL << 32) +#define NXF_STATE_ADMIN (1ULL << 34) -#define NXF_ONE_TIME (0x0005ULL<<32) +#define NXF_SC_HELPER (1ULL << 36) +#define NXF_PERSISTENT (1ULL << 38) + +#define NXF_ONE_TIME (0x0005ULL << 32) #define NXF_INIT_SET (NXF_STATE_ADMIN) /* address types */ -#define NXA_TYPE_IPV4 1 -#define NXA_TYPE_IPV6 2 +#define NXA_TYPE_IPV4 0x0001 +#define NXA_TYPE_IPV6 0x0002 + +#define NXA_TYPE_NONE 0x0000 +#define NXA_TYPE_ANY 0x00FF -#define NXA_MOD_BCAST (1<<8) +#define NXA_TYPE_ADDR 0x0003 +#define NXA_TYPE_MASK 0x0013 +#define NXA_TYPE_RANGE 0x0023 -#define NXA_TYPE_ANY ((uint16_t)-1) +#define NXA_MOD_BCAST 0x0100 +#define NXA_MOD_LBACK 0x0200 #else /* _VX_NETWORK_H */ diff --git a/kernel/network_cmd.h b/kernel/network_cmd.h index 06c7055..3327777 100644 --- a/kernel/network_cmd.h +++ b/kernel/network_cmd.h @@ -24,15 +24,61 @@ struct vcmd_net_create { #define VCMD_net_migrate VC_CMD(NETMIG, 1, 0) -#define VCMD_net_add VC_CMD(NETALT, 1, 0) -#define VCMD_net_remove VC_CMD(NETALT, 2, 0) +#define VCMD_net_add_v0 VC_CMD(NETALT, 1, 0) +#define VCMD_net_remove_v0 VC_CMD(NETALT, 2, 0) struct vcmd_net_addr_v0 { uint16_t type; uint16_t count; - uint32_t ip[4]; - uint32_t mask[4]; - /* more to come */ + struct in_addr ip[4]; + struct in_addr mask[4]; +}; + +#define VCMD_net_add_ipv4 VC_CMD(NETALT, 1, 1) +#define VCMD_net_remove_ipv4 VC_CMD(NETALT, 2, 1) + +struct vcmd_net_addr_ipv4_v1 { + uint16_t type; + uint16_t flags; + struct in_addr ip; + struct in_addr mask; +}; + +#define VCMD_net_add_ipv6 VC_CMD(NETALT, 3, 1) +#define VCMD_net_remove_ipv6 VC_CMD(NETALT, 4, 1) + +struct vcmd_net_addr_ipv6_v1 { + uint16_t type; + uint16_t flags; + uint32_t prefix; + struct in6_addr ip; + struct in6_addr mask; +}; + +#define VCMD_add_match_ipv4 VC_CMD(NETALT, 5, 0) +#define VCMD_get_match_ipv4 VC_CMD(NETALT, 6, 0) + +struct vcmd_match_ipv4_v0 { + uint16_t type; + uint16_t flags; + uint16_t parent; + uint16_t prefix; + struct in_addr ip; + struct in_addr ip2; + struct in_addr mask; +}; + +#define VCMD_add_match_ipv6 VC_CMD(NETALT, 7, 0) +#define VCMD_get_match_ipv6 VC_CMD(NETALT, 8, 0) + +struct vcmd_match_ipv6_v0 { + uint16_t type; + uint16_t flags; + uint16_t parent; + uint16_t prefix; + struct in6_addr ip; + struct in6_addr ip2; + struct in6_addr mask; }; diff --git a/lib/Makefile-files b/lib/Makefile-files index 9d5b6df..670e56b 100644 --- a/lib/Makefile-files +++ b/lib/Makefile-files @@ -133,7 +133,17 @@ lib_v21_SRCS = lib/syscall_setccaps-v21.hc \ lib/syscall_schedinfo-v21.hc \ lib/syscall_getccaps-v21.hc \ lib/syscall_getsched.c \ - lib/syscall_getsched-v21.hc + lib/syscall_getsched-v21.hc \ + lib/syscall_ctxcreate-v21.hc + +lib_v22_SRCS = lib/syscall_setsched-v22.hc \ + lib/syscall_fsetiattr.c \ + lib/syscall_fsetiattr-v22.hc \ + lib/syscall_fgetiattr.c \ + lib/syscall_fgetiattr-v22.hc + +lib_netv2_SRCS = lib/syscall_netadd-netv2.hc \ + lib/syscall_netremove-netv2.hc if ENSC_HAVE_C99_COMPILER lib_v13_SRCS += lib/syscall_adddlimit-v13.hc \ @@ -180,6 +190,8 @@ lib_SRCS = lib/syscall.c \ $(lib_v11_SRCS) \ $(lib_v13_SRCS) \ $(lib_v21_SRCS) \ + $(lib_v22_SRCS) \ + $(lib_netv2_SRCS) \ $(ensc_fmt_SRCS) include_HEADERS += lib/vserver.h diff --git a/lib/syscall_ctxcreate-v13.hc b/lib/syscall_ctxcreate-v13.hc index 930ed18..250f1fd 100644 --- a/lib/syscall_ctxcreate-v13.hc +++ b/lib/syscall_ctxcreate-v13.hc @@ -21,9 +21,14 @@ #endif static inline ALWAYSINLINE xid_t -vc_ctx_create_v13(xid_t xid) +vc_ctx_create_v13(xid_t xid, struct vc_ctx_flags *flags) { xid_t res = vserver(VCMD_ctx_create_v0, CTX_USER2KERNEL(xid), 0); + if (flags) { + /* no sane way to report errors here */ + vc_set_cflags(xid, flags); + } + return CTX_KERNEL2USER(res); } diff --git a/lib/syscall_ctxcreate-v21.hc b/lib/syscall_ctxcreate-v21.hc new file mode 100644 index 0000000..91e145b --- /dev/null +++ b/lib/syscall_ctxcreate-v21.hc @@ -0,0 +1,46 @@ +// $Id$ --*- c -*-- + +// Copyright (C) 2007 Daniel Hokka Zakrisson +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; version 2 of the License. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + +#ifdef HAVE_CONFIG_H +# include +#endif +#include + +static inline ALWAYSINLINE xid_t +vc_ctx_create_v21(xid_t xid, struct vc_ctx_flags *flags) +{ + struct vcmd_ctx_create data = { + .flagword = (VC_VXF_STATE_SETUP | VC_VXF_STATE_ADMIN | + VC_VXF_STATE_INIT) + }; + xid_t res; + + if (flags) + data.flagword = flags->flagword & flags->mask; + + res = vserver(VCMD_ctx_create, CTX_USER2KERNEL(xid), &data); + res = CTX_KERNEL2USER(res); + + if (res != VC_NOCTX) { + if (utilvserver_checkCompatConfig() & VC_VCI_SPACES) { + sys_unshare(CLONE_NEWUTS | CLONE_NEWIPC); + } + } + + return res; +} diff --git a/lib/syscall_ctxcreate.c b/lib/syscall_ctxcreate.c index 747546b..541213e 100644 --- a/lib/syscall_ctxcreate.c +++ b/lib/syscall_ctxcreate.c @@ -21,17 +21,26 @@ #endif #include "vserver.h" -#include "vserver-internal.h" #include "virtual.h" +#if defined(VC_ENABLE_API_V13) && defined(VC_ENABLE_API_V21) +# define VC_MULTIVERSION_SYSCALL 1 +#endif +#include "vserver-internal.h" + #if defined(VC_ENABLE_API_V13) # include "syscall_ctxcreate-v13.hc" #endif -#if defined(VC_ENABLE_API_V13) +#if defined(VC_ENABLE_API_V21) +# include "syscall_ctxcreate-v21.hc" +#endif + +#if defined(VC_ENABLE_API_V13) || defined(VC_ENABLE_API_V21) xid_t -vc_ctx_create(xid_t xid) +vc_ctx_create(xid_t xid, struct vc_ctx_flags *flags) { - CALL_VC(CALL_VC_V13A(vc_ctx_create, xid)); + CALL_VC(CALL_VC_V21 (vc_ctx_create, xid, flags), + CALL_VC_V13A(vc_ctx_create, xid, flags)); } #endif diff --git a/lib/syscall_fgetiattr-v22.hc b/lib/syscall_fgetiattr-v22.hc new file mode 100644 index 0000000..22d8c2e --- /dev/null +++ b/lib/syscall_fgetiattr-v22.hc @@ -0,0 +1,44 @@ +// $Id$ --*- c++ -*-- + +// Copyright (C) 2007 Daniel Hokka Zakrisson +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; version 2 of the License. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + +#ifdef HAVE_CONFIG_H +# include +#endif + +static inline ALWAYSINLINE int +vc_fget_iattr_v22(int fd, xid_t *ctx, uint_least32_t *flags, + uint_least32_t *mask) +{ + int ret; + struct vcmd_ctx_fiattr_v0 data = { .mask = 0 }; + + if (mask) + data.mask = *mask; + ret = vserver(VCMD_fget_iattr, fd, &data); + if (ret) + return ret; + + if (ctx) + *ctx = data.xid; + if (flags) + *flags = data.flags; + if (mask) + *mask = data.mask; + + return 0; +} diff --git a/lib/syscall_fgetiattr.c b/lib/syscall_fgetiattr.c new file mode 100644 index 0000000..6cf14f4 --- /dev/null +++ b/lib/syscall_fgetiattr.c @@ -0,0 +1,38 @@ +// $Id$ --*- c++ -*-- + +// Copyright (C) 2007 Daniel Hokka Zakrisson +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; version 2 of the License. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "vserver.h" +#include "virtual.h" +#include "vserver-internal.h" + +#if defined(VC_ENABLE_API_V22) +# include "syscall_fgetiattr-v22.hc" +#endif + +#if defined(VC_ENABLE_API_V22) +int +vc_fget_iattr(int fd, xid_t *ctx, uint_least32_t *flags, + uint_least32_t *mask) +{ + CALL_VC(CALL_VC_V22(vc_fget_iattr, fd, ctx, flags, mask)); +} +#endif diff --git a/lib/syscall_fsetiattr-v22.hc b/lib/syscall_fsetiattr-v22.hc new file mode 100644 index 0000000..ba2dfab --- /dev/null +++ b/lib/syscall_fsetiattr-v22.hc @@ -0,0 +1,34 @@ +// $Id$ --*- c++ -*-- + +// Copyright (C) 2007 Daniel Hokka Zakrisson +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; version 2 of the License. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + +#ifdef HAVE_CONFIG_H +# include +#endif + +static inline ALWAYSINLINE int +vc_fset_iattr_v22(int fd, xid_t ctx, uint_least32_t flags, + uint_least32_t mask) +{ + struct vcmd_ctx_fiattr_v0 data = { + .xid = ctx, + .flags = flags, + .mask = mask + }; + + return vserver(VCMD_fset_iattr, fd, &data); +} diff --git a/lib/syscall_fsetiattr.c b/lib/syscall_fsetiattr.c new file mode 100644 index 0000000..b93a2fd --- /dev/null +++ b/lib/syscall_fsetiattr.c @@ -0,0 +1,38 @@ +// $Id$ --*- c++ -*-- + +// Copyright (C) 2007 Daniel Hokka Zakrisson +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; version 2 of the License. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "vserver.h" +#include "virtual.h" +#include "vserver-internal.h" + +#if defined(VC_ENABLE_API_V22) +# include "syscall_fsetiattr-v22.hc" +#endif + +#if defined(VC_ENABLE_API_V22) +int +vc_fset_iattr(int fd, xid_t ctx, uint_least32_t flags, + uint_least32_t mask) +{ + CALL_VC(CALL_VC_V22(vc_fset_iattr, fd, ctx, flags, mask)); +} +#endif diff --git a/lib/syscall_netadd-net.hc b/lib/syscall_netadd-net.hc index f408d90..6238f41 100644 --- a/lib/syscall_netadd-net.hc +++ b/lib/syscall_netadd-net.hc @@ -21,17 +21,27 @@ #endif static inline ALWAYSINLINE int -vc_net_add_net(nid_t nid, struct vc_net_nx const *info) +vc_net_add_net(nid_t nid, struct vc_net_addr const *info) { struct vcmd_net_addr_v0 k_info; size_t i; - k_info.type = NETTYPE_USER2KERNEL(info->type); - k_info.count = info->count; - for (i = 0; i < sizeof(k_info.ip) / sizeof(*k_info.ip); i++) - k_info.ip[i] = info->ip[i]; - for (i = 0; i < sizeof(k_info.mask) / sizeof(*k_info.mask); i++) - k_info.mask[i] = info->mask[i]; - - return vserver(VCMD_net_add, NID_USER2KERNEL(nid), &k_info); + k_info.type = info->vna_type & (VC_NXA_TYPE_IPV4|VC_NXA_TYPE_IPV6); + k_info.count = 1; + switch (info->vna_type & ~VC_NXA_TYPE_ADDR) { + case VC_NXA_TYPE_IPV4: + k_info.ip[0].s_addr = info->vna_v4_ip.s_addr; + k_info.mask[0].s_addr = info->vna_v4_mask.s_addr; + break; + case VC_NXA_TYPE_IPV6: + for (i = 0; i < 4; i++) + k_info.ip[i].s_addr = info->vna_v6_ip.s6_addr32[i]; + k_info.mask[0].s_addr = info->vna_prefix; + break; + default: + errno = EINVAL; + return -1; + } + + return vserver(VCMD_net_add_v0, NID_USER2KERNEL(nid), &k_info); } diff --git a/lib/syscall_netadd-netv2.hc b/lib/syscall_netadd-netv2.hc new file mode 100644 index 0000000..d9489bf --- /dev/null +++ b/lib/syscall_netadd-netv2.hc @@ -0,0 +1,52 @@ +// $Id$ --*- c -*-- + +// Copyright (C) 2007 Daniel Hokka Zakrisson +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; version 2 of the License. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + +#ifdef HAVE_CONFIG_H +# include +#endif + +static inline ALWAYSINLINE int +vc_net_add_netv2(nid_t nid, struct vc_net_addr const *info) +{ + switch (info->vna_type & (VC_NXA_TYPE_IPV4 | VC_NXA_TYPE_IPV6)) { + case VC_NXA_TYPE_IPV4: { + struct vcmd_net_addr_ipv4_v1 k_info; + + k_info.type = info->vna_type & ~VC_NXA_TYPE_IPV4; + k_info.flags = info->vna_flags; + k_info.ip.s_addr = info->vna_v4_ip.s_addr; + k_info.mask.s_addr = info->vna_v4_mask.s_addr; + + return vserver(VCMD_net_add_ipv4, NID_USER2KERNEL(nid), &k_info); + } + case VC_NXA_TYPE_IPV6: { + struct vcmd_net_addr_ipv6_v1 k_info; + + k_info.type = info->vna_type & ~VC_NXA_TYPE_IPV6; + k_info.flags = info->vna_flags; + k_info.prefix = info->vna_prefix; + memcpy(k_info.ip.s6_addr, info->vna_v6_ip.s6_addr, sizeof(struct in6_addr)); + memcpy(k_info.mask.s6_addr, info->vna_v6_mask.s6_addr, sizeof(struct in6_addr)); + + return vserver(VCMD_net_add_ipv6, NID_USER2KERNEL(nid), &k_info); + } + default: + errno = EINVAL; + return -1; + } +} diff --git a/lib/syscall_netadd.c b/lib/syscall_netadd.c index 176c93c..d25d25f 100644 --- a/lib/syscall_netadd.c +++ b/lib/syscall_netadd.c @@ -20,23 +20,34 @@ # include #endif +#include + #include "vserver.h" -#include "vserver-internal.h" #include "virtual.h" +#if defined(VC_ENABLE_API_NET) && defined(VC_ENABLE_API_NETV2) +# define VC_MULTIVERSION_SYSCALL 1 +#endif +#include "vserver-internal.h" + #if defined(VC_ENABLE_API_NET) # include "syscall_netadd-net.hc" #endif -#if defined(VC_ENABLE_API_NET) +#if defined(VC_ENABLE_API_NETV2) +# include "syscall_netadd-netv2.hc" +#endif + +#if defined(VC_ENABLE_API_NET) || defined(VC_ENABLE_API_NETV2) int -vc_net_add(nid_t nid, struct vc_net_nx const *info) +vc_net_add(nid_t nid, struct vc_net_addr const *info) { if (info==0) { errno = EFAULT; return -1; } - CALL_VC(CALL_VC_NET(vc_net_add, nid, info)); + CALL_VC(CALL_VC_NETV2(vc_net_add, nid, info), + CALL_VC_NET (vc_net_add, nid, info)); } #endif diff --git a/lib/syscall_netremove-net.hc b/lib/syscall_netremove-net.hc index 0ec02e9..3f34ba5 100644 --- a/lib/syscall_netremove-net.hc +++ b/lib/syscall_netremove-net.hc @@ -21,17 +21,31 @@ #endif static inline ALWAYSINLINE int -vc_net_remove_net(nid_t nid, struct vc_net_nx const *info) +vc_net_remove_net(nid_t nid, struct vc_net_addr const *info) { struct vcmd_net_addr_v0 k_info; size_t i; - k_info.type = NETTYPE_USER2KERNEL(info->type); - k_info.count = info->count; - for (i = 0; i < sizeof(k_info.ip) / sizeof(*k_info.ip); i++) - k_info.ip[i] = info->ip[i]; - for (i = 0; i < sizeof(k_info.mask) / sizeof(*k_info.mask); i++) - k_info.mask[i] = info->mask[i]; - - return vserver(VCMD_net_remove, NID_USER2KERNEL(nid), &k_info); + k_info.type = info->vna_type & (VC_NXA_TYPE_IPV4|VC_NXA_TYPE_IPV6); + k_info.count = 1; + switch (info->vna_type) { + case VC_NXA_TYPE_IPV4 | VC_NXA_TYPE_ADDR: + k_info.ip[0].s_addr = info->vna_v4_ip.s_addr; + k_info.mask[0].s_addr = info->vna_v4_mask.s_addr; + break; + case VC_NXA_TYPE_IPV6 | VC_NXA_TYPE_ADDR: + for (i = 0; i < 4; i++) + k_info.ip[i].s_addr = info->vna_v6_ip.s6_addr32[i]; + k_info.mask[0].s_addr = info->vna_prefix; + break; + case VC_NXA_TYPE_ANY: + k_info.type = (uint16_t) -1; + k_info.count = -1; + break; + default: + errno = EINVAL; + return -1; + } + + return vserver(VCMD_net_remove_v0, NID_USER2KERNEL(nid), &k_info); } diff --git a/lib/syscall_netremove-netv2.hc b/lib/syscall_netremove-netv2.hc new file mode 100644 index 0000000..2ca4331 --- /dev/null +++ b/lib/syscall_netremove-netv2.hc @@ -0,0 +1,65 @@ +// $Id$ --*- c -*-- + +// Copyright (C) 2007 Daniel Hokka Zakrisson +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; version 2 of the License. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + +#ifdef HAVE_CONFIG_H +# include +#endif + +static inline ALWAYSINLINE int +vc_net_remove_netv2(nid_t nid, struct vc_net_addr const *info) +{ + if (info->vna_type == VC_NXA_TYPE_ANY) { + struct vcmd_net_addr_ipv4_v1 k_ipv4; + struct vcmd_net_addr_ipv6_v1 k_ipv6; + int ret; + + k_ipv4.type = VC_NXA_TYPE_ANY; + k_ipv6.type = VC_NXA_TYPE_ANY; + + ret = vserver(VCMD_net_remove_ipv4, NID_USER2KERNEL(nid), &k_ipv4); + if (ret == -1) + return -1; + return vserver(VCMD_net_remove_ipv6, NID_USER2KERNEL(nid), &k_ipv6); + } + switch (info->vna_type & (VC_NXA_TYPE_IPV4 | VC_NXA_TYPE_IPV6)) { + case VC_NXA_TYPE_IPV4: { + struct vcmd_net_addr_ipv4_v1 k_info; + + k_info.type = info->vna_type & ~VC_NXA_TYPE_IPV4; + k_info.flags = info->vna_flags; + k_info.ip.s_addr = info->vna_v4_ip.s_addr; + k_info.mask.s_addr = info->vna_v4_mask.s_addr; + + return vserver(VCMD_net_remove_ipv4, NID_USER2KERNEL(nid), &k_info); + } + case VC_NXA_TYPE_IPV6: { + struct vcmd_net_addr_ipv6_v1 k_info; + + k_info.type = info->vna_type & ~VC_NXA_TYPE_IPV6; + k_info.flags = info->vna_flags; + k_info.prefix = info->vna_prefix; + memcpy(k_info.ip.s6_addr, info->vna_v6_ip.s6_addr, sizeof(struct in6_addr)); + memcpy(k_info.mask.s6_addr, info->vna_v6_mask.s6_addr, sizeof(struct in6_addr)); + + return vserver(VCMD_net_remove_ipv6, NID_USER2KERNEL(nid), &k_info); + } + default: + errno = EINVAL; + return -1; + } +} diff --git a/lib/syscall_netremove.c b/lib/syscall_netremove.c index ef59982..c4a48d4 100644 --- a/lib/syscall_netremove.c +++ b/lib/syscall_netremove.c @@ -20,23 +20,34 @@ # include #endif +#include + #include "vserver.h" -#include "vserver-internal.h" #include "virtual.h" +#if defined(VC_ENABLE_API_NET) && defined(VC_ENABLE_API_NETV2) +# define VC_MULTIVERSION_SYSCALL 1 +#endif +#include "vserver-internal.h" + #if defined(VC_ENABLE_API_NET) # include "syscall_netremove-net.hc" #endif -#if defined(VC_ENABLE_API_NET) +#if defined(VC_ENABLE_API_NETV2) +# include "syscall_netremove-netv2.hc" +#endif + +#if defined(VC_ENABLE_API_NET) || defined(VC_ENABLE_API_NETV2) int -vc_net_remove(nid_t nid, struct vc_net_nx const *info) +vc_net_remove(nid_t nid, struct vc_net_addr const *info) { if (info==0) { errno = EFAULT; return -1; } - CALL_VC(CALL_VC_NET(vc_net_remove, nid, info)); + CALL_VC(CALL_VC_NETV2(vc_net_remove, nid, info), + CALL_VC_NET (vc_net_remove, nid, info)); } #endif diff --git a/lib/syscall_setsched-v22.hc b/lib/syscall_setsched-v22.hc new file mode 100644 index 0000000..0af5e92 --- /dev/null +++ b/lib/syscall_setsched-v22.hc @@ -0,0 +1,43 @@ +// $Id$ --*- c -*-- + +// Copyright (C) 2007 Daniel Hokka Zakrisson +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; version 2 of the License. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "vserver.h" + +static inline ALWAYSINLINE int +vc_set_sched_v22(xid_t xid, struct vc_set_sched const *data) +{ + struct vcmd_sched_v5 k_data; + + k_data.fill_rate[0] = data->fill_rate; + k_data.interval[0] = data->interval; + k_data.fill_rate[1] = data->fill_rate2; + k_data.interval[1] = data->interval2; + k_data.tokens = data->tokens; + k_data.tokens_min = data->tokens_min; + k_data.tokens_max = data->tokens_max; + k_data.prio_bias = data->priority_bias; + k_data.cpu_id = data->cpu_id; + k_data.bucket_id = data->bucket_id; + k_data.mask = data->set_mask; + + return vserver(VCMD_set_sched, CTX_USER2KERNEL(xid), &k_data); +} diff --git a/lib/syscall_setsched.c b/lib/syscall_setsched.c index 5ee42e3..51101b6 100644 --- a/lib/syscall_setsched.c +++ b/lib/syscall_setsched.c @@ -38,10 +38,15 @@ # include "syscall_setsched-v21.hc" #endif +#ifdef VC_ENABLE_API_V22 +# include "syscall_setsched-v22.hc" +#endif + int vc_set_sched(xid_t xid, struct vc_set_sched const *data) { - CALL_VC(CALL_VC_V21 (vc_set_sched,xid,data), + CALL_VC(CALL_VC_V22 (vc_set_sched,xid,data), + CALL_VC_V21 (vc_set_sched,xid,data), CALL_VC_V13B (vc_set_sched,xid,data), CALL_VC_V13OBS(vc_set_sched,xid,data)); } diff --git a/lib/vserver-internal.h b/lib/vserver-internal.h index 6478e5d..4e71afd 100644 --- a/lib/vserver-internal.h +++ b/lib/vserver-internal.h @@ -50,7 +50,7 @@ inline static ALWAYSINLINE void vc_noop0() {} # define CALL_VC(...) \ do { \ int ver = utilvserver_checkCompatVersion(); \ - uint_least32_t conf = utilvserver_checkCompatConfig(); \ + uint_least32_t UNUSED conf = utilvserver_checkCompatConfig(); \ if (ver==-1) return -1; \ VC_SUFFIX, __VA_ARGS__, VC_PREFIX; \ errno = ENOSYS; \ @@ -114,18 +114,36 @@ inline static ALWAYSINLINE void vc_noop0() {} # define CALL_VC_V21(F,...) CALL_VC_NOOP #endif -#ifdef VC_ENABLE_API_V21 +#if defined(VC_ENABLE_API_V21) || defined(VC_ENABLE_API_V22) || defined(VC_ENABLE_API_V23) # define CALL_VC_SPACES(F,...) CALL_VC_GENERAL_CONFIG(VC_VCI_SPACES, spaces, F, __VA_ARGS__) #else # define CALL_VC_SPACES(F,...) CALL_VC_NOOP #endif +#ifdef VC_ENABLE_API_V22 +# define CALL_VC_V22(F,...) CALL_VC_GENERAL(0x00020200, v22, F, __VA_ARGS__) +#else +# define CALL_VC_V22(F,...) CALL_VC_NOOP +#endif + +#ifdef VC_ENABLE_API_V23 +# define CALL_VC_V23(F,...) CALL_VC_GENERAL(0x00020300, v23, F, __VA_ARGS__) +#else +# define CALL_VC_V23(F,...) CALL_VC_NOOP +#endif + #ifdef VC_ENABLE_API_NET # define CALL_VC_NET(F,...) CALL_VC_GENERAL(0x00010016, net, F, __VA_ARGS__) #else # define CALL_VC_NET(F,...) CALL_VC_NOOP #endif +#if defined(VC_ENABLE_API_NETV2) +# define CALL_VC_NETV2(F,...) CALL_VC_GENERAL_CONFIG(VC_VCI_NETV2, netv2, F, __VA_ARGS__) +#else +# define CALL_VC_NETV2(F,...) CALL_VC_NOOP +#endif + #ifdef VC_ENABLE_API_FSCOMPAT # define CALL_VC_FSCOMPAT(F,...) CALL_VC_GENERAL(0x00010000, fscompat, F, __VA_ARGS__) #else @@ -205,24 +223,6 @@ inline static ALWAYSINLINE void vc_noop0() {} # define NID_KERNEL2USER(X) (X) #endif -#if 1 -# define NETTYPE_USER2KERNEL(X) ((X)==vcNET_IPV4 ? NXA_TYPE_IPV4 : \ - (X)==vcNET_IPV6 ? NXA_TYPE_IPV6 : \ - (X)==vcNET_IPV4B ? (NXA_TYPE_IPV4 | NXA_MOD_BCAST) : \ - (X)==vcNET_IPV6B ? (NXA_TYPE_IPV6 | NXA_MOD_BCAST) : \ - (X)==vcNET_ANY ? NXA_TYPE_ANY : \ - (X)) -# define NETTYPE_KERNEL2USER(X) ((X)==NXA_TYPE_IPV4 ? vcNET_IPV4 : \ - (X)==NXA_TYPE_IPV6 ? vcNET_IPV6 : \ - (X)==(NXA_TYPE_IPV4|NXA_MOD_BCAST) ? vcNET_IPV4B : \ - (X)==(NXA_TYPE_IPV6|NXA_MOD_BCAST) ? vcNET_IPV6B : \ - (X)==NXA_TYPE_ANY ? vcNET_ANY : \ - (X)) -#else -# define NETTYPE_USER2KERNEL(X) (X) -# define NETTYPE_KERNEL2USER(X) (X) -#endif - #define CDLIM_USER2KERNEL(X) ((X)==VC_CDLIM_UNSET ? CDLIM_UNSET : \ (X)==VC_CDLIM_INFINITY ? CDLIM_INFINITY : \ (X)==VC_CDLIM_KEEP ? CDLIM_KEEP : \ diff --git a/lib/vserver.h b/lib/vserver.h index dbee3e6..e0ca826 100644 --- a/lib/vserver.h +++ b/lib/vserver.h @@ -29,6 +29,7 @@ #include #include #include +#include #ifndef IS_DOXYGEN #if defined(__GNUC__) @@ -259,6 +260,7 @@ // the VCI bit values #define VC_VCI_NO_DYNAMIC (1 << 0) #define VC_VCI_SPACES (1 << 10) +#define VC_VCI_NETV2 (1 << 11) // the device mapping flags @@ -273,6 +275,21 @@ #define VC_VXM_SET_REAPER 0x00000002 +// the network address flags +#define VC_NXA_TYPE_IPV4 0x0001 +#define VC_NXA_TYPE_IPV6 0x0002 + +#define VC_NXA_TYPE_NONE 0x0000 +#define VC_NXA_TYPE_ANY 0x00FF + +#define VC_NXA_TYPE_ADDR 0x0010 +#define VC_NXA_TYPE_MASK 0x0020 +#define VC_NXA_TYPE_RANGE 0x0040 + +#define VC_NXA_MOD_BCAST 0x0100 +#define VC_NXA_MOD_LBACK 0x0200 + + #ifndef CLONE_NEWNS # define CLONE_NEWNS 0x00020000 #endif @@ -393,7 +410,7 @@ extern "C" { * * \returns the xid of the created context, or VC_NOCTX on errors. \c errno * will be set appropriately. */ - xid_t vc_ctx_create(xid_t xid); + xid_t vc_ctx_create(xid_t xid, struct vc_ctx_flags *flags); /** \brief Moves the current process into the specified context. * \ingroup syscalls @@ -601,15 +618,25 @@ extern "C" { nid_t vc_get_task_nid(pid_t pid); int vc_get_nx_info(nid_t nid, struct vc_nx_info *) VC_ATTR_NONNULL((2)); - typedef enum { vcNET_IPV4=1, vcNET_IPV6=2, - vcNET_IPV4B=0x101, vcNET_IPV6B=0x102, - vcNET_ANY=~0 } vc_net_nx_type; - - struct vc_net_nx { - vc_net_nx_type type; - size_t count; - uint32_t ip[4]; - uint32_t mask[4]; + struct vc_net_addr { + uint16_t vna_type; + uint16_t vna_flags; + uint16_t vna_prefix; + uint16_t vna_parent; + union { + struct { + struct in_addr ip; + struct in_addr mask; + } ipv4; + struct { + struct in6_addr ip; + struct in6_addr mask; + } ipv6; + } u; +#define vna_v4_ip u.ipv4.ip +#define vna_v4_mask u.ipv4.mask +#define vna_v6_ip u.ipv6.ip +#define vna_v6_mask u.ipv6.mask }; struct vc_net_flags { @@ -620,8 +647,8 @@ extern "C" { nid_t vc_net_create(nid_t nid); int vc_net_migrate(nid_t nid); - int vc_net_add(nid_t nid, struct vc_net_nx const *info); - int vc_net_remove(nid_t nid, struct vc_net_nx const *info); + int vc_net_add(nid_t nid, struct vc_net_addr const *info); + int vc_net_remove(nid_t nid, struct vc_net_addr const *info); int vc_get_nflags(nid_t, struct vc_net_flags *); int vc_set_nflags(nid_t, struct vc_net_flags const *); @@ -640,6 +667,9 @@ extern "C" { int vc_set_iattr(char const *filename, xid_t xid, uint_least32_t flags, uint_least32_t mask) VC_ATTR_NONNULL((1)); + int vc_fset_iattr(int fd, xid_t xid, + uint_least32_t flags, uint_least32_t mask); + /** \brief Returns information about attributes and assigned context of a file. * \ingroup syscalls * @@ -669,6 +699,10 @@ extern "C" { int vc_get_iattr(char const *filename, xid_t * /*@null@*/ xid, uint_least32_t * /*@null@*/ flags, uint_least32_t * /*@null@*/ mask) VC_ATTR_NONNULL((1)); + + int vc_fget_iattr(int fd, xid_t * /*@null@*/ xid, + uint_least32_t * /*@null@*/ flags, + uint_least32_t * /*@null@*/ mask) VC_ATTR_NONNULL((4)); /** \brief Returns the context of \c filename * \ingroup syscalls diff --git a/lib_internal/sys_unshare.h b/lib_internal/sys_unshare.h new file mode 100644 index 0000000..c174bad --- /dev/null +++ b/lib_internal/sys_unshare.h @@ -0,0 +1,43 @@ +// $Id$ --*- c -*-- + +// Copyright (C) 2007 Daniel Hokka Zakrisson +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; version 2 of the License. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + +#ifndef H_UTIL_VSERVER_SRC_SYS_UNSHARE_H +#define H_UTIL_VSERVER_SRC_SYS_UNSHARE_H + +#include +#include "lib/syscall-wrap.h" +#define __NR_sys_unshare __NR_unshare + +#ifndef ENSC_SYSCALL_TRADITIONAL +# include + +inline static UNUSED ALWAYSINLINE +_syscall1(int, sys_unshare, int, flags) +#else +inline static UNUSED ALWAYSINLINE +int sys_unshare(int flags) +{ + return syscall(__NR_sys_clone, flags); +} +#endif + +#undef __NR_sys_unshare + +#define ENSC_HAVE_SYSUNSHARE 1 + +#endif // H_UTIL_VSERVER_SRC_SYS_UNSHARE_H diff --git a/src/chbind.c b/src/chbind.c index 02cc8b4..8002d5c 100644 --- a/src/chbind.c +++ b/src/chbind.c @@ -242,61 +242,6 @@ readBcast(char const *str, uint32_t *bcast) } } -#if defined(VC_ENABLE_API_NET) -static void -make_nx(nid_t nid, uint32_t bcast, size_t nbaddrs, struct vc_ip_mask_pair *ips) -{ - size_t i; - struct vc_net_nx addr; - - if (nid == VC_DYNAMIC_NID) { - nid = vc_net_create(VC_DYNAMIC_NID); - if (nid == (nid_t) -1) { - perror("chbind: vc_net_create()"); - exit(wrapper_exit_code); - } - } - else { - if (vc_net_create(nid) == (nid_t) -1) { - if (errno == EEXIST) { - if (vc_net_migrate(nid) != 0) { - perror("chbind: vc_net_migrate()"); - exit(wrapper_exit_code); - } - else - return; - } - else { - perror("chbind: vc_net_create()"); - exit(wrapper_exit_code); - } - } - } - - addr.type = vcNET_IPV4B; - addr.count = 1; - addr.ip[0] = bcast; - addr.mask[0] = 0; - - if (vc_net_add(nid, &addr) != 1) { - perror("chbind: vc_net_add()"); - exit(wrapper_exit_code); - } - - for (i = 0; i < nbaddrs; i++) { - addr.type = vcNET_IPV4; - addr.count = 1; - addr.ip[0] = ips[i].ip; - addr.mask[0] = ips[i].mask; - - if (vc_net_add(nid, &addr) != 1) { - perror("chbind: vc_net_add()"); - exit(wrapper_exit_code); - } - } -} -#endif - int main (int argc, char *argv[]) { size_t const nb_ipv4root = vc_get_nb_ipv4root(); @@ -315,11 +260,7 @@ int main (int argc, char *argv[]) case CMD_VERSION : showVersion(); case CMD_SILENT : is_silent = true; break; case CMD_BCAST : readBcast(optarg, &bcast); break; -#if defined(VC_ENABLE_API_NET) - case CMD_NID : nid = Evc_nidopt2nid(optarg,true); break; -#else case CMD_NID : WRITE_MSG(2, "WARNING: --nid is not supported by this version\n"); break; -#endif case CMD_IP : if (nbaddrs>=nb_ipv4root) { WRITE_MSG(2, "Too many IP numbers, max 16\n"); @@ -342,16 +283,10 @@ int main (int argc, char *argv[]) exit(wrapper_exit_code); } -#if !defined(VC_ENABLE_API_NET) && !defined(VC_ENABLE_API_COMPAT) && !defined(VC_ENABLE_API_LEGACY) -# error can not build 'chbind' without network virtualization API +#if !defined(VC_ENABLE_API_COMPAT) && !defined(VC_ENABLE_API_LEGACY) +# warning building a dummy chbind-compat with no available APIs #endif -#if defined(VC_ENABLE_API_NET) - if (vc_isSupported(vcFEATURE_VNET)) { - make_nx(nid, bcast, nbaddrs, ips); - } - else -#endif #if defined(VC_ENABLE_API_COMPAT) || defined(VC_ENABLE_API_LEGACY) if (vc_set_ipv4root(bcast,nbaddrs,ips)!=0) { perror("chbind: vc_set_ipv4root()"); diff --git a/src/naddress.c b/src/naddress.c index 035bc9f..e890396 100644 --- a/src/naddress.c +++ b/src/naddress.c @@ -57,6 +57,9 @@ #define CMD_SET 0x2004 #define CMD_IP 0x2010 #define CMD_BCAST 0x2011 +#define CMD_MASK 0x2012 +#define CMD_RANGE 0x2013 +#define CMD_LBACK 0x2014 int wrapper_exit_code = 255; @@ -71,12 +74,15 @@ CMDLINE_OPTIONS[] = { { "set", no_argument, 0, CMD_SET }, { "nid", required_argument, 0, CMD_NID }, { "ip", required_argument, 0, CMD_IP }, + { "mask", required_argument, 0, CMD_MASK }, + { "range", required_argument, 0, CMD_RANGE }, { "bcast", required_argument, 0, CMD_BCAST }, + { "lback", required_argument, 0, CMD_LBACK }, { 0,0,0,0 } }; struct vc_ips { - struct vc_net_nx a; + struct vc_net_addr a; struct vc_ips *next; }; @@ -197,32 +203,53 @@ int ifconfig_getaddr ( } static int -convertAddress(const char *str, vc_net_nx_type *type, void *dst) +convertAddress(const char *str, uint16_t *type, void *dst) { int ret; - if (type) *type = vcNET_IPV4; + if (type) *type = VC_NXA_TYPE_IPV4; ret = inet_pton(AF_INET, str, dst); if (ret==0) { - if (type) *type = vcNET_IPV6; + if (type) *type = VC_NXA_TYPE_IPV6; ret = inet_pton(AF_INET6, str, dst); } return ret > 0 ? 0 : -1; } static void -readIP(char const *str, struct vc_ips **ips) +ipv6PrefixToMask(struct in6_addr *mask, int prefix) { - if (ifconfig_getaddr(str, &(*ips)->a.ip[0], &(*ips)->a.mask[0], NULL)==-1) { + int i; + mask->s6_addr32[0] = mask->s6_addr32[1] = mask->s6_addr32[2] = mask->s6_addr32[3] = 0; + for (i = 0; (i << 3) < prefix; i++) { + mask->s6_addr[i] = 0xff; + } + if ((i << 3) > prefix) + mask->s6_addr[i-1] = ~((1 << (prefix & 0x07)) - 1); +} + +static int +maskToPrefix(void *data, int limit) +{ + uint8_t *mask = data; + int prefix; + for (prefix = 0; prefix < limit && mask[prefix >> 3] & (1 << (prefix & 0x07)); prefix++) + ; + return prefix; +} + +static void +readIP(char const *str, struct vc_ips **ips, uint16_t type) +{ + if (ifconfig_getaddr(str, &(*ips)->a.vna_v4_ip.s_addr, &(*ips)->a.vna_v4_mask.s_addr, NULL)==-1) { char *pt; char tmpopt[strlen(str)+1]; - uint32_t *mask = (*ips)->a.mask; strcpy(tmpopt,str); pt = strchr(tmpopt,'/'); if (pt) *pt++ = '\0'; - if (convertAddress(tmpopt, &(*ips)->a.type, (*ips)->a.ip) == -1) { + if (convertAddress(tmpopt, &(*ips)->a.vna_type, &(*ips)->a.vna_v4_ip.s_addr) == -1) { WRITE_MSG(2, "Invalid IP number '"); WRITE_STR(2, tmpopt); WRITE_MSG(2, "'\n"); @@ -230,12 +257,15 @@ readIP(char const *str, struct vc_ips **ips) } if (pt==0) { - switch ((*ips)->a.type) { - case vcNET_IPV4: - mask[0] = htonl(0xffffff00); + switch ((*ips)->a.vna_type) { + case VC_NXA_TYPE_IPV4: + (*ips)->a.vna_v4_mask.s_addr = htonl(0xffffff00); + (*ips)->a.vna_prefix = 24; break; - case vcNET_IPV6: - mask[0] = 64; + case VC_NXA_TYPE_IPV6: + (*ips)->a.vna_prefix = 64; + (*ips)->a.vna_v6_mask.s6_addr32[0] = (*ips)->a.vna_v6_mask.s6_addr32[1] = 0xffffffff; + (*ips)->a.vna_v6_mask.s6_addr32[2] = (*ips)->a.vna_v6_mask.s6_addr32[3] = 0x00000000; break; default: break; } @@ -245,10 +275,10 @@ readIP(char const *str, struct vc_ips **ips) if (strchr(pt,'.')==0 && strchr(pt,':')==0) { unsigned long sz, limit = 0; - switch ((*ips)->a.type) { - case vcNET_IPV4: limit = 32; break; - case vcNET_IPV6: limit = 128; break; - default: break; + switch ((*ips)->a.vna_type) { + case VC_NXA_TYPE_IPV4: limit = 32; break; + case VC_NXA_TYPE_IPV6: limit = 128; break; + default: break; } if (!isNumberUnsigned(pt, &sz, true) || sz > limit) { @@ -258,30 +288,48 @@ readIP(char const *str, struct vc_ips **ips) exit(wrapper_exit_code); } - switch ((*ips)->a.type) { - case vcNET_IPV4: - mask[0] = htonl(~((1 << (32 - sz)) - 1)); + (*ips)->a.vna_prefix = sz; + switch ((*ips)->a.vna_type) { + case VC_NXA_TYPE_IPV4: + (*ips)->a.vna_v4_mask.s_addr = htonl(~((1 << (32 - sz)) - 1)); break; - case vcNET_IPV6: - mask[0] = sz; + case VC_NXA_TYPE_IPV6: + ipv6PrefixToMask(&(*ips)->a.vna_v6_mask, (*ips)->a.vna_prefix); break; default: break; } } - else { - if (convertAddress(pt, NULL, &(*ips)->a.mask) == -1) { + else { + int af, limit; + void *mask; + switch ((*ips)->a.vna_type) { + case VC_NXA_TYPE_IPV4: + af = AF_INET; + mask = &(*ips)->a.vna_v4_mask.s_addr; + limit = 32; + break; + case VC_NXA_TYPE_IPV6: + af = AF_INET6; + mask = (*ips)->a.vna_v6_mask.s6_addr32; + limit = 128; + break; + default: + return; + } + if (inet_pton(af, pt, mask) < 0) { WRITE_MSG(2, "Invalid netmask '"); WRITE_STR(2, pt); WRITE_MSG(2, "'\n"); exit(wrapper_exit_code); } + (*ips)->a.vna_prefix = maskToPrefix(mask, limit); } } } else - (*ips)->a.type = vcNET_IPV4; + (*ips)->a.vna_type = VC_NXA_TYPE_IPV4; + (*ips)->a.vna_type |= type; - (*ips)->a.count = 1; (*ips)->next = calloc(1, sizeof(struct vc_ips)); *ips = (*ips)->next; } @@ -291,28 +339,41 @@ readBcast(char const *str, struct vc_ips **ips) { uint32_t bcast; if (ifconfig_getaddr(str, NULL, NULL, &bcast)==-1){ - if (convertAddress(str, NULL, &bcast) == -1) { + if (inet_pton(AF_INET, str, &bcast) < 0) { WRITE_MSG(2, "Invalid broadcast number '"); WRITE_STR(2, optarg); WRITE_MSG(2, "'\n"); exit(wrapper_exit_code); } } - (*ips)->a.ip[0] = bcast; - (*ips)->a.count = 1; - (*ips)->a.type = vcNET_IPV4B; + (*ips)->a.vna_v4_ip.s_addr = bcast; + (*ips)->a.vna_type = VC_NXA_TYPE_IPV4 | VC_NXA_MOD_BCAST; (*ips)->next = calloc(1, sizeof(struct vc_ips)); *ips = (*ips)->next; } static void -tellAddress(struct vc_net_nx *addr, bool silent) +tellAddress(struct vc_net_addr *addr, bool silent) { char buf[41]; + int af; + void *address; if (silent) return; - if (inet_ntop(addr->type == vcNET_IPV6 ? AF_INET6 : AF_INET, - addr->ip, buf, sizeof(buf)) == NULL) { + switch (addr->vna_type & (VC_NXA_TYPE_IPV4 | VC_NXA_TYPE_IPV6)) { + case VC_NXA_TYPE_IPV4: + af = AF_INET; + address = &addr->vna_v4_ip.s_addr; + break; + case VC_NXA_TYPE_IPV6: + af = AF_INET6; + address = addr->vna_v6_ip.s6_addr32; + break; + default: + WRITE_MSG(1, " "); + return; + } + if (inet_ntop(af, address, buf, sizeof(buf)) == NULL) { WRITE_MSG(1, " "); return; } @@ -326,7 +387,7 @@ doit(struct Arguments *args) struct vc_ips *ips; if (args->do_set) { - struct vc_net_nx remove = { .type = vcNET_ANY }; + struct vc_net_addr remove = { .vna_type = VC_NXA_TYPE_ANY }; if (vc_net_remove(args->nid, &remove) == -1) { perror(ENSC_WRAPPERS_PREFIX "vc_net_remove()"); exit(wrapper_exit_code); @@ -338,7 +399,7 @@ doit(struct Arguments *args) WRITE_MSG(1, "Adding"); for (ips = &args->head; ips->next; ips = ips->next) { tellAddress(&ips->a, args->is_silent); - if (vc_net_add(args->nid, &ips->a) != (int)ips->a.count) { + if (vc_net_add(args->nid, &ips->a) == -1) { if (!args->is_silent) WRITE_MSG(1, "\n"); perror(ENSC_WRAPPERS_PREFIX "vc_net_add()"); @@ -353,7 +414,9 @@ doit(struct Arguments *args) WRITE_MSG(1, "Removing"); for (ips = &args->head; ips->next; ips = ips->next) { tellAddress(&ips->a, args->is_silent); - if (vc_net_remove(args->nid, &ips->a) != (int)ips->a.count) { + if (vc_net_remove(args->nid, &ips->a) == -1) { + if (!args->is_silent) + WRITE_MSG(1, "\n"); perror(ENSC_WRAPPERS_PREFIX "vc_net_remove()"); exit(wrapper_exit_code); } @@ -387,8 +450,11 @@ int main (int argc, char *argv[]) case CMD_ADD : args.do_add = true; break; case CMD_REMOVE : args.do_remove = true; break; case CMD_SET : args.do_set = true; break; - case CMD_IP : readIP(optarg, &ips); break; + case CMD_IP : readIP(optarg, &ips, VC_NXA_TYPE_ADDR); break; + case CMD_MASK : readIP(optarg, &ips, VC_NXA_TYPE_MASK); break; + case CMD_RANGE : readIP(optarg, &ips, VC_NXA_TYPE_RANGE); break; case CMD_BCAST : readBcast(optarg, &ips); break; + case CMD_LBACK : readIP(optarg, &ips, VC_NXA_TYPE_ADDR | VC_NXA_MOD_LBACK); break; default : WRITE_MSG(2, "Try '"); WRITE_STR(2, argv[0]); diff --git a/src/rpm-fake.c b/src/rpm-fake.c index 1689e2d..d41e181 100644 --- a/src/rpm-fake.c +++ b/src/rpm-fake.c @@ -245,7 +245,7 @@ setupContext(xid_t xid, char const **xid_str) xid_t rc=VC_NOCTX; if ((xid==VC_DYNAMIC_XID || !vc_is_dynamic_xid(xid)) && - (rc=vc_ctx_create(xid))==VC_NOCTX && + (rc=vc_ctx_create(xid, NULL))==VC_NOCTX && errno!=EEXIST) { perror(ENSC_WRAPPERS_PREFIX "vc_ctx_create()"); exit(255); diff --git a/src/vcontext.c b/src/vcontext.c index 7f1a809..0f2f95b 100644 --- a/src/vcontext.c +++ b/src/vcontext.c @@ -254,7 +254,7 @@ doit(struct Arguments const *args, int argc, char *argv[]) doSyncStage0(p, args->do_disconnect); if (args->do_create) { - xid = vc_ctx_create(args->xid); + xid = vc_ctx_create(args->xid, NULL); if (xid==VC_NOCTX) { switch (errno) { case EEXIST : diff --git a/vserver-start/main.c b/vserver-start/main.c index 3ff03e4..953daf2 100644 --- a/vserver-start/main.c +++ b/vserver-start/main.c @@ -166,7 +166,7 @@ int main(int UNUSED argc, char UNUSED *argv[]) execScriptlets(&cfgdir, opts.VSERVER_NAME, "prepre-start"); activateInterfaces(&cfg.interfaces); - xid = Evc_ctx_create(cfg.xid); + xid = Evc_ctx_create(cfg.xid, NULL); setCFlag(xid, VC_VXF_INFO_NAMESPACE); mountVserver(&cfg); -- 1.8.1.5