Add support for the various new APIs in 2.2 and 2.3, in particular, netv2.
authorDaniel Hokka Zakrisson <daniel@hozac.com>
Wed, 8 Aug 2007 20:05:26 +0000 (20:05 +0000)
committerDaniel Hokka Zakrisson <daniel@hozac.com>
Wed, 8 Aug 2007 20:05:26 +0000 (20:05 +0000)
git-svn-id: http://svn.linux-vserver.org/svn/util-vserver/trunk@2578 94cd875c-1c1d-0410-91d2-eb244daf1a30

30 files changed:
AUTHORS
configure.ac
ensc_wrappers/wrappers-vserver.hc
kernel/inode_cmd.h
kernel/network.h
kernel/network_cmd.h
lib/Makefile-files
lib/syscall_ctxcreate-v13.hc
lib/syscall_ctxcreate-v21.hc [new file with mode: 0644]
lib/syscall_ctxcreate.c
lib/syscall_fgetiattr-v22.hc [new file with mode: 0644]
lib/syscall_fgetiattr.c [new file with mode: 0644]
lib/syscall_fsetiattr-v22.hc [new file with mode: 0644]
lib/syscall_fsetiattr.c [new file with mode: 0644]
lib/syscall_netadd-net.hc
lib/syscall_netadd-netv2.hc [new file with mode: 0644]
lib/syscall_netadd.c
lib/syscall_netremove-net.hc
lib/syscall_netremove-netv2.hc [new file with mode: 0644]
lib/syscall_netremove.c
lib/syscall_setsched-v22.hc [new file with mode: 0644]
lib/syscall_setsched.c
lib/vserver-internal.h
lib/vserver.h
lib_internal/sys_unshare.h [new file with mode: 0644]
src/chbind.c
src/naddress.c
src/rpm-fake.c
src/vcontext.c
vserver-start/main.c

diff --git a/AUTHORS b/AUTHORS
index db53813..7041e8c 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -1 +1,2 @@
 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
+Daniel Hokka Zakrisson <daniel@hozac.com>
index f72d67d..5caea3a 100644 (file)
@@ -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]);;
index 6d1047e..a1e1e0a 100644 (file)
@@ -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;
 }
index ed26aa1..39a825a 100644 (file)
@@ -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;
index 2b84f07..c3b0323 100644 (file)
@@ -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 */
index 06c7055..3327777 100644 (file)
@@ -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;
 };
 
 
index 9d5b6df..670e56b 100644 (file)
@@ -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
index 930ed18..250f1fd 100644 (file)
 #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 (file)
index 0000000..91e145b
--- /dev/null
@@ -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 <config.h>
+#endif
+#include <lib_internal/sys_unshare.h>
+
+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;
+}
index 747546b..541213e 100644 (file)
 #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 (file)
index 0000000..22d8c2e
--- /dev/null
@@ -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 <config.h>
+#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 (file)
index 0000000..6cf14f4
--- /dev/null
@@ -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 <config.h>
+#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 (file)
index 0000000..ba2dfab
--- /dev/null
@@ -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 <config.h>
+#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 (file)
index 0000000..b93a2fd
--- /dev/null
@@ -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 <config.h>
+#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
index f408d90..6238f41 100644 (file)
 #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 (file)
index 0000000..d9489bf
--- /dev/null
@@ -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 <config.h>
+#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;
+  }
+}
index 176c93c..d25d25f 100644 (file)
 #  include <config.h>
 #endif
 
+#include <string.h>
+
 #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
index 0ec02e9..3f34ba5 100644 (file)
 #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 (file)
index 0000000..2ca4331
--- /dev/null
@@ -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 <config.h>
+#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;
+  }
+}
index ef59982..c4a48d4 100644 (file)
 #  include <config.h>
 #endif
 
+#include <string.h>
+
 #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 (file)
index 0000000..0af5e92
--- /dev/null
@@ -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 <config.h>
+#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);
+}
index 5ee42e3..51101b6 100644 (file)
 #  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));
 }
index 6478e5d..4e71afd 100644 (file)
@@ -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     : \
index dbee3e6..e0ca826 100644 (file)
@@ -29,6 +29,7 @@
 #include <stdbool.h>
 #include <sys/types.h>
 #include <sched.h>
+#include <netinet/in.h>
 
 #ifndef IS_DOXYGEN
 #if defined(__GNUC__)
 // 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
 #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 (file)
index 0000000..c174bad
--- /dev/null
@@ -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 <unistd.h>
+#include "lib/syscall-wrap.h"
+#define __NR_sys_unshare       __NR_unshare
+
+#ifndef ENSC_SYSCALL_TRADITIONAL
+#  include <errno.h>
+
+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
index 02cc8b4..8002d5c 100644 (file)
@@ -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()");
index 035bc9f..e890396 100644 (file)
@@ -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, " <unknown address type>");
+      return;
+  }
+  if (inet_ntop(af, address, buf, sizeof(buf)) == NULL) {
     WRITE_MSG(1, " <conversion failed>");
     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]);
index 1689e2d..d41e181 100644 (file)
@@ -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);
index 7f1a809..0f2f95b 100644 (file)
@@ -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   :
index 3ff03e4..953daf2 100644 (file)
@@ -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);