diff -NurpP --minimal linux-2.6.12.2-vs2.0-rc5/include/linux/vserver/network_cmd.h linux-2.6.12.2-vs2.0-rc5-net2/include/linux/vserver/network_cmd.h --- linux-2.6.12.2-vs2.0-rc5/include/linux/vserver/network_cmd.h 2005-07-05 19:05:21.000000000 +0200 +++ linux-2.6.12.2-vs2.0-rc5-net2/include/linux/vserver/network_cmd.h 2005-07-05 22:54:53.000000000 +0200 @@ -35,11 +35,11 @@ struct vcmd_net_create { #define VCMD_net_add VC_CMD(NETALT, 1, 0) #define VCMD_net_remove VC_CMD(NETALT, 2, 0) -struct vcmd_net_nx_v0 { +struct vcmd_net_addr_v0 { uint16_t type; uint16_t count; - uint32_t ip[4]; - uint32_t mask[4]; + uint32_t *ip; + uint32_t *mask; /* more to come */ }; @@ -48,8 +48,14 @@ struct vcmd_net_nx_v0 { extern int vc_net_create(uint32_t, void __user *); extern int vc_net_migrate(uint32_t, void __user *); +extern int vc_net_add(uint32_t, void __user *); +extern int vc_net_remove(uint32_t, void __user *); + #endif /* __KERNEL__ */ + +/* flag commands */ + #define VCMD_get_nflags VC_CMD(FLAGS, 5, 0) #define VCMD_set_nflags VC_CMD(FLAGS, 6, 0) @@ -64,9 +70,8 @@ extern int vc_set_nflags(uint32_t, void #endif /* __KERNEL__ */ -#define IPF_STATE_SETUP (1ULL<<32) -#define IPF_ONE_TIME (0x0001ULL<<32) +/* network caps commands */ #define VCMD_get_ncaps VC_CMD(FLAGS, 7, 0) #define VCMD_set_ncaps VC_CMD(FLAGS, 8, 0) diff -NurpP --minimal linux-2.6.12.2-vs2.0-rc5/include/linux/vserver/network.h linux-2.6.12.2-vs2.0-rc5-net2/include/linux/vserver/network.h --- linux-2.6.12.2-vs2.0-rc5/include/linux/vserver/network.h 2005-07-05 19:05:21.000000000 +0200 +++ linux-2.6.12.2-vs2.0-rc5-net2/include/linux/vserver/network.h 2005-07-05 19:05:56.000000000 +0200 @@ -11,15 +11,27 @@ #define NB_IPV4ROOT 16 -/* context flags */ +/* network flags */ #define NXF_STATE_SETUP (1ULL<<32) #define NXF_STATE_HELPER (1ULL<<36) +#define NXF_ONE_TIME (0x0001ULL<<32) + #define NXF_INIT_SET (0) +/* address types */ + +#define NXA_TYPE_IPV4 1 +#define NXA_TYPE_IPV6 2 + +#define NXA_MOD_BCAST (1<<8) + +#define NXA_TYPE_ANY (~0) + + #ifdef __KERNEL__ #include diff -NurpP --minimal linux-2.6.12.2-vs2.0-rc5/kernel/vserver/network.c linux-2.6.12.2-vs2.0-rc5-net2/kernel/vserver/network.c --- linux-2.6.12.2-vs2.0-rc5/kernel/vserver/network.c 2005-07-05 19:05:22.000000000 +0200 +++ linux-2.6.12.2-vs2.0-rc5-net2/kernel/vserver/network.c 2005-07-06 00:35:18.000000000 +0200 @@ -578,6 +578,84 @@ int vc_net_migrate(uint32_t id, void __u return 0; } +int vc_net_add(uint32_t nid, void __user *data) +{ + struct vcmd_net_addr_v0 vc_data; + uint32_t ip[NB_IPV4ROOT], mask[NB_IPV4ROOT]; + struct nx_info *nxi; + int index, pos, ret = 0; + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + if (data && copy_from_user (&vc_data, data, sizeof(vc_data))) + return -EFAULT; + + if (!vc_data.count) + return 0; + if (vc_data.count > NB_IPV4ROOT || !vc_data.ip || !vc_data.mask || + copy_from_user(&ip, vc_data.ip, vc_data.count * sizeof(*ip)) || + copy_from_user(&mask, vc_data.mask, vc_data.count * sizeof(*mask))) + return -EFAULT; + + nxi = locate_nx_info(nid); + if (!nxi) + return -ESRCH; + + switch (vc_data.type) { + case NXA_TYPE_IPV4: + index = 0; + while ((index < vc_data.count) && + ((pos = nxi->nbipv4) < NB_IPV4ROOT)) { + nxi->ipv4[pos] = vc_data.ip[index]; + nxi->mask[pos] = vc_data.mask[index]; + index++; + nxi->nbipv4++; + } + ret = index; + break; + + case NXA_TYPE_IPV4|NXA_MOD_BCAST: + nxi->v4_bcast = vc_data.ip[0]; + ret = 1; + break; + + default: + ret = -EINVAL; + break; + } + + put_nx_info(nxi); + return ret; +} + +int vc_net_remove(uint32_t nid, void __user *data) +{ + struct vcmd_net_addr_v0 vc_data; + struct nx_info *nxi; + int ret = 0; + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + if (data && copy_from_user (&vc_data, data, sizeof(vc_data))) + return -EFAULT; + + nxi = locate_nx_info(nid); + if (!nxi) + return -ESRCH; + + switch (vc_data.type) { + case NXA_TYPE_ANY: + nxi->nbipv4 = 0; + break; + + default: + ret = -EINVAL; + break; + } + + put_nx_info(nxi); + return ret; +} int vc_get_nflags(uint32_t id, void __user *data) { @@ -594,7 +672,7 @@ int vc_get_nflags(uint32_t id, void __us vc_data.flagword = nxi->nx_flags; /* special STATE flag handling */ - vc_data.mask = vx_mask_flags(~0UL, nxi->nx_flags, IPF_ONE_TIME); + vc_data.mask = vx_mask_flags(~0UL, nxi->nx_flags, NXF_ONE_TIME); put_nx_info(nxi); @@ -619,7 +697,7 @@ int vc_set_nflags(uint32_t id, void __us return -ESRCH; /* special STATE flag handling */ - mask = vx_mask_mask(vc_data.mask, nxi->nx_flags, IPF_ONE_TIME); + mask = vx_mask_mask(vc_data.mask, nxi->nx_flags, NXF_ONE_TIME); trigger = (mask & nxi->nx_flags) ^ (mask & vc_data.flagword); nxi->nx_flags = vx_mask_flags(nxi->nx_flags, diff -NurpP --minimal linux-2.6.12.2-vs2.0-rc5/kernel/vserver/switch.c linux-2.6.12.2-vs2.0-rc5-net2/kernel/vserver/switch.c --- linux-2.6.12.2-vs2.0-rc5/kernel/vserver/switch.c 2005-07-05 19:05:22.000000000 +0200 +++ linux-2.6.12.2-vs2.0-rc5-net2/kernel/vserver/switch.c 2005-07-05 19:05:56.000000000 +0200 @@ -218,6 +218,12 @@ long do_vserver(uint32_t cmd, uint32_t i return vc_net_create(id, data); case VCMD_net_migrate: return vc_net_migrate(id, data); +#ifndef CONFIG_VSERVER_LEGACYNET + case VCMD_net_add: + return vc_net_add(id, data); + case VCMD_net_remove: + return vc_net_remove(id, data); +#endif } return -ENOSYS;