diff -NurpP --minimal linux-2.6.38.2-vs2.3.0.37-rc10/include/linux/vserver/network_cmd.h linux-2.6.38.2-vs2.3.0.37-rc11/include/linux/vserver/network_cmd.h --- linux-2.6.38.2-vs2.3.0.37-rc10/include/linux/vserver/network_cmd.h 2011-01-29 02:01:07.000000000 +0100 +++ linux-2.6.38.2-vs2.3.0.37-rc11/include/linux/vserver/network_cmd.h 2011-04-04 10:26:39.000000000 +0200 @@ -45,8 +45,8 @@ struct vcmd_net_addr_v0 { 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) +#define VCMD_net_add_ipv4_v1 VC_CMD(NETALT, 1, 1) +#define VCMD_net_remove_ipv4_v1 VC_CMD(NETALT, 2, 1) struct vcmd_net_addr_ipv4_v1 { uint16_t type; @@ -55,6 +55,17 @@ struct vcmd_net_addr_ipv4_v1 { struct in_addr mask; }; +#define VCMD_net_add_ipv4 VC_CMD(NETALT, 1, 2) +#define VCMD_net_remove_ipv4 VC_CMD(NETALT, 2, 2) + +struct vcmd_net_addr_ipv4_v2 { + uint16_t type; + uint16_t flags; + struct in_addr ip; + struct in_addr ip2; + struct in_addr mask; +}; + #define VCMD_net_add_ipv6 VC_CMD(NETALT, 3, 1) #define VCMD_net_remove_ipv6 VC_CMD(NETALT, 4, 1) @@ -100,7 +111,10 @@ extern int vc_net_migrate(struct nx_info extern int vc_net_add(struct nx_info *, void __user *); extern int vc_net_remove(struct nx_info *, void __user *); +extern int vc_net_add_ipv4_v1(struct nx_info *, void __user *); extern int vc_net_add_ipv4(struct nx_info *, void __user *); + +extern int vc_net_remove_ipv4_v1(struct nx_info *, void __user *); extern int vc_net_remove_ipv4(struct nx_info *, void __user *); extern int vc_net_add_ipv6(struct nx_info *, void __user *); diff -NurpP --minimal linux-2.6.38.2-vs2.3.0.37-rc10/kernel/vserver/network.c linux-2.6.38.2-vs2.3.0.37-rc11/kernel/vserver/network.c --- linux-2.6.38.2-vs2.3.0.37-rc10/kernel/vserver/network.c 2011-04-03 19:13:41.000000000 +0200 +++ linux-2.6.38.2-vs2.3.0.37-rc11/kernel/vserver/network.c 2011-04-04 10:27:08.000000000 +0200 @@ -616,6 +616,26 @@ int do_add_v4_addr(struct nx_info *nxi, return 0; } +int do_remove_v4_addr(struct nx_info *nxi, __be32 ip, __be32 ip2, __be32 mask, + uint16_t type, uint16_t flags) +{ + struct nx_addr_v4 *nxa = &nxi->v4; + + switch (type) { +/* case NXA_TYPE_ADDR: + break; */ + + case NXA_TYPE_ANY: + __dealloc_nx_addr_v4_all(xchg(&nxa->next, NULL)); + memset(nxa, 0, sizeof(*nxa)); + break; + + default: + return -EINVAL; + } + return 0; +} + int vc_net_add(struct nx_info *nxi, void __user *data) { @@ -678,7 +698,7 @@ int vc_net_remove(struct nx_info *nxi, v } -int vc_net_add_ipv4(struct nx_info *nxi, void __user *data) +int vc_net_add_ipv4_v1(struct nx_info *nxi, void __user *data) { struct vcmd_net_addr_ipv4_v1 vc_data; @@ -693,10 +713,6 @@ int vc_net_add_ipv4(struct nx_info *nxi, return do_add_v4_addr(nxi, vc_data.ip.s_addr, 0, vc_data.mask.s_addr, vc_data.type, vc_data.flags); - case NXA_TYPE_RANGE: - return do_add_v4_addr(nxi, vc_data.ip.s_addr, - vc_data.mask.s_addr, 0, vc_data.type, vc_data.flags); - case NXA_TYPE_ADDR | NXA_MOD_BCAST: nxi->v4_bcast = vc_data.ip; break; @@ -711,20 +727,26 @@ int vc_net_add_ipv4(struct nx_info *nxi, return 0; } -int vc_net_remove_ipv4(struct nx_info *nxi, void __user *data) +int vc_net_add_ipv4(struct nx_info *nxi, void __user *data) { - struct vcmd_net_addr_ipv4_v1 vc_data; + struct vcmd_net_addr_ipv4_v2 vc_data; if (data && copy_from_user(&vc_data, data, sizeof(vc_data))) return -EFAULT; switch (vc_data.type) { -/* case NXA_TYPE_ADDR: - break; */ + case NXA_TYPE_ADDR: + case NXA_TYPE_MASK: + case NXA_TYPE_RANGE: + return do_add_v4_addr(nxi, vc_data.ip.s_addr, vc_data.ip2.s_addr, + vc_data.mask.s_addr, vc_data.type, vc_data.flags); - case NXA_TYPE_ANY: - __dealloc_nx_addr_v4_all(xchg(&nxi->v4.next, NULL)); - memset(&nxi->v4, 0, sizeof(nxi->v4)); + case NXA_TYPE_ADDR | NXA_MOD_BCAST: + nxi->v4_bcast = vc_data.ip; + break; + + case NXA_TYPE_ADDR | NXA_MOD_LBACK: + nxi->v4_lback = vc_data.ip; break; default: @@ -733,6 +755,27 @@ int vc_net_remove_ipv4(struct nx_info *n return 0; } +int vc_net_remove_ipv4_v1(struct nx_info *nxi, void __user *data) +{ + struct vcmd_net_addr_ipv4_v1 vc_data; + + if (data && copy_from_user(&vc_data, data, sizeof(vc_data))) + return -EFAULT; + + return do_add_v4_addr(nxi, vc_data.ip.s_addr, 0, + vc_data.mask.s_addr, vc_data.type, vc_data.flags); +} + +int vc_net_remove_ipv4(struct nx_info *nxi, void __user *data) +{ + struct vcmd_net_addr_ipv4_v2 vc_data; + + if (data && copy_from_user(&vc_data, data, sizeof(vc_data))) + return -EFAULT; + + return do_add_v4_addr(nxi, vc_data.ip.s_addr, 0, + vc_data.mask.s_addr, vc_data.type, vc_data.flags); +} #ifdef CONFIG_IPV6 diff -NurpP --minimal linux-2.6.38.2-vs2.3.0.37-rc10/kernel/vserver/switch.c linux-2.6.38.2-vs2.3.0.37-rc11/kernel/vserver/switch.c --- linux-2.6.38.2-vs2.3.0.37-rc10/kernel/vserver/switch.c 2011-01-29 02:01:07.000000000 +0100 +++ linux-2.6.38.2-vs2.3.0.37-rc11/kernel/vserver/switch.c 2011-04-04 10:16:59.000000000 +0200 @@ -233,8 +233,15 @@ long do_vcmd(uint32_t cmd, uint32_t id, case VCMD_net_remove: return vc_net_remove(nxi, data); + case VCMD_net_add_ipv4_v1: + return vc_net_add_ipv4_v1(nxi, data); + /* this is version 2 */ case VCMD_net_add_ipv4: return vc_net_add_ipv4(nxi, data); + + case VCMD_net_remove_ipv4_v1: + return vc_net_remove_ipv4_v1(nxi, data); + /* this is version 2 */ case VCMD_net_remove_ipv4: return vc_net_remove_ipv4(nxi, data); #ifdef CONFIG_IPV6