-diff -NurpP linux-3.7-vs2.3.5.1/include/linux/vs_inet.h linux-3.7-vs2.3.5.1.1/include/linux/vs_inet.h
---- linux-3.7-vs2.3.5.1/include/linux/vs_inet.h 2012-12-11 15:56:32.000000000 +0000
-+++ linux-3.7-vs2.3.5.1.1/include/linux/vs_inet.h 2012-12-13 12:52:33.000000000 +0000
-@@ -81,12 +81,15 @@ int v4_addr_in_nx_info(struct nx_info *n
- (nxi->v4_bcast.s_addr == addr))
- goto out;
- ret = 5;
-+
- /* check for v4 addresses */
-+ spin_lock(&nxi->addr_lock);
- for (nxa = &nxi->v4; nxa; nxa = nxa->next)
- if (v4_addr_match(nxa, addr, tmask))
- goto out;
- ret = 0;
- out:
-+ spin_unlock(&nxi->addr_lock);
- vxdprintk(VXD_CBIT(net, 0),
- "v4_addr_in_nx_info(%p[#%u]," NIPQUAD_FMT ",%04x) = %d",
- nxi, nxi ? nxi->nx_id : 0, NIPQUAD(addr), tmask, ret);
-@@ -104,11 +107,16 @@ static inline
- int v4_nx_addr_in_nx_info(struct nx_info *nxi, struct nx_addr_v4 *nxa, uint16_t mask)
- {
- struct nx_addr_v4 *ptr;
-+ int ret = 1;
-
-+ spin_lock(&nxi->addr_lock);
- for (ptr = &nxi->v4; ptr; ptr = ptr->next)
- if (v4_nx_addr_match(ptr, nxa, mask))
-- return 1;
-- return 0;
-+ goto out;
-+ ret = 0;
-+out:
-+ spin_unlock(&nxi->addr_lock);
-+ return ret;
- }
-
- #include <net/inet_sock.h>
-diff -NurpP linux-3.7-vs2.3.5.1/include/linux/vs_inet6.h linux-3.7-vs2.3.5.1.1/include/linux/vs_inet6.h
---- linux-3.7-vs2.3.5.1/include/linux/vs_inet6.h 2012-12-11 15:56:32.000000000 +0000
-+++ linux-3.7-vs2.3.5.1.1/include/linux/vs_inet6.h 2012-12-13 12:52:39.000000000 +0000
-@@ -45,11 +45,14 @@ int v6_addr_in_nx_info(struct nx_info *n
-
- if (!nxi)
- goto out;
-+
-+ spin_lock(&nxi->addr_lock);
- for (nxa = &nxi->v6; nxa; nxa = nxa->next)
- if (v6_addr_match(nxa, addr, mask))
- goto out;
- ret = 0;
- out:
-+ spin_unlock(&nxi->addr_lock);
- vxdprintk(VXD_CBIT(net, 0),
- "v6_addr_in_nx_info(%p[#%u],%pI6,%04x) = %d",
- nxi, nxi ? nxi->nx_id : 0, addr, mask, ret);
-@@ -67,11 +70,16 @@ static inline
- int v6_nx_addr_in_nx_info(struct nx_info *nxi, struct nx_addr_v6 *nxa, uint16_t mask)
- {
- struct nx_addr_v6 *ptr;
-+ int ret = 1;
-
-+ spin_lock(&nxi->addr_lock);
- for (ptr = &nxi->v6; ptr; ptr = ptr->next)
- if (v6_nx_addr_match(ptr, nxa, mask))
-- return 1;
-- return 0;
-+ goto out;
-+ ret = 0;
-+out:
-+ spin_unlock(&nxi->addr_lock);
-+ return ret;
- }
-
-
-diff -NurpP linux-3.7-vs2.3.5.1/include/linux/vserver/network.h linux-3.7-vs2.3.5.1.1/include/linux/vserver/network.h
---- linux-3.7-vs2.3.5.1/include/linux/vserver/network.h 2012-12-11 15:56:32.000000000 +0000
-+++ linux-3.7-vs2.3.5.1.1/include/linux/vserver/network.h 2012-12-13 13:40:52.000000000 +0000
-@@ -109,6 +109,7 @@ struct nx_info {
- uint64_t nx_flags; /* network flag word */
- uint64_t nx_ncaps; /* network capabilities */
-
-+ spinlock_t addr_lock; /* protect address changes */
- struct in_addr v4_lback; /* Loopback address */
- struct in_addr v4_bcast; /* Broadcast address */
- struct nx_addr_v4 v4; /* First/Single ipv4 address */
-diff -NurpP linux-3.7-vs2.3.5.1/kernel/vserver/network.c linux-3.7-vs2.3.5.1.1/kernel/vserver/network.c
---- linux-3.7-vs2.3.5.1/kernel/vserver/network.c 2012-12-11 15:56:33.000000000 +0000
-+++ linux-3.7-vs2.3.5.1.1/kernel/vserver/network.c 2012-12-13 13:48:35.000000000 +0000
-@@ -131,6 +131,7 @@ static struct nx_info *__alloc_nx_info(n
- INIT_HLIST_NODE(&new->nx_hlist);
- atomic_set(&new->nx_usecnt, 0);
- atomic_set(&new->nx_tasks, 0);
-+ spin_lock_init(&new->addr_lock);
- new->nx_state = 0;
-
- new->nx_flags = NXF_INIT_SET;
-@@ -593,26 +597,31 @@ int do_add_v4_addr(struct nx_info *nxi,
- uint16_t type, uint16_t flags)
- {
- struct nx_addr_v4 *nxa = &nxi->v4;
-+ struct nx_addr_v4 *new = __alloc_nx_addr_v4();
-+
-+ if (IS_ERR(new))
-+ return PTR_ERR(new);
-
-+ spin_lock(&nxi->addr_lock);
- if (NX_IPV4(nxi)) {
- /* locate last entry */
- for (; nxa->next; nxa = nxa->next);
-- nxa->next = __alloc_nx_addr_v4();
-- nxa = nxa->next;
--
-- if (IS_ERR(nxa))
-- return PTR_ERR(nxa);
-- }
-+ nxa->next = new;
-+ nxa = new;
-+ new = NULL;
-
-- if (nxi->v4.next)
- /* remove single ip for ip list */
- nxi->nx_flags &= ~NXF_SINGLE_IP;
-+ }
-
- nxa->ip[0].s_addr = ip;
- nxa->ip[1].s_addr = ip2;
- nxa->mask.s_addr = mask;
- nxa->type = type;
- nxa->flags = flags;
-+ spin_unlock(&nxi->addr_lock);
-+ if (new)
-+ __dealloc_nx_addr_v4(new);
- return 0;
- }
-
-@@ -620,20 +629,25 @@ int do_remove_v4_addr(struct nx_info *nx
- uint16_t type, uint16_t flags)
- {
- struct nx_addr_v4 *nxa = &nxi->v4;
-+ struct nx_addr_v4 *old = NULL;
-+ int ret = 0;
-
-+ spin_lock(&nxi->addr_lock);
- switch (type) {
- /* case NXA_TYPE_ADDR:
- break; */
-
- case NXA_TYPE_ANY:
-- __dealloc_nx_addr_v4_all(xchg(&nxa->next, NULL));
-+ old = xchg(&nxa->next, NULL);
- memset(nxa, 0, sizeof(*nxa));
- break;
-
- default:
-- return -EINVAL;
-+ ret = -EINVAL;
- }
-- return 0;
-+ spin_unlock(&nxi->addr_lock);
-+ __dealloc_nx_addr_v4_all(old);
-+ return ret;
- }
-
-
-@@ -687,10 +701,7 @@ int vc_net_remove(struct nx_info *nxi, v
-
- switch (vc_data.type) {
- case NXA_TYPE_ANY:
-- __dealloc_nx_addr_v4_all(xchg(&nxi->v4.next, NULL));
-- memset(&nxi->v4, 0, sizeof(nxi->v4));
-- break;
--
-+ return do_remove_v4_addr(nxi, 0, 0, 0, vc_data.type, 0);
- default:
- return -EINVAL;
- }
-@@ -782,15 +793,18 @@ int do_add_v6_addr(struct nx_info *nxi,
- uint32_t prefix, uint16_t type, uint16_t flags)
- {
- struct nx_addr_v6 *nxa = &nxi->v6;
-+ struct nx_addr_v6 *new = __alloc_nx_addr_v6();
-
-+ if (IS_ERR(new))
-+ return PTR_ERR(new);
-+
-+ spin_lock(&nxi->addr_lock);
- if (NX_IPV6(nxi)) {
- /* locate last entry */
- for (; nxa->next; nxa = nxa->next);
-- nxa->next = __alloc_nx_addr_v6();
-- nxa = nxa->next;
--
-- if (IS_ERR(nxa))
-- return PTR_ERR(nxa);
-+ nxa->next = new;
-+ nxa = new;
-+ new = NULL;
- }
-
- nxa->ip = *ip;
-@@ -798,6 +812,9 @@ int do_add_v6_addr(struct nx_info *nxi,
- nxa->prefix = prefix;
- nxa->type = type;
- nxa->flags = flags;
-+ spin_unlock(&nxi->addr_lock);
-+ if (new)
-+ __dealloc_nx_addr_v6(new);
- return 0;
- }
-
-diff -NurpP linux-3.7-vs2.3.5.1/kernel/vserver/network.c linux-3.7-vs2.3.5.1.1/kernel/vserver/network.c
---- linux-3.7-vs2.3.5.1/kernel/vserver/network.c 2012-12-11 15:56:33.000000000 +0000
-+++ linux-3.7-vs2.3.5.1.1/kernel/vserver/network.c 2012-12-13 13:48:35.000000000 +0000
-@@ -804,6 +818,31 @@ int do_add_v6_addr(struct nx_info *nxi,
- return 0;
- }
-
-+int do_remove_v6_addr(struct nx_info *nxi,
-+ struct in6_addr *ip, struct in6_addr *mask,
-+ uint32_t prefix, uint16_t type, uint16_t flags)
-+{
-+ struct nx_addr_v6 *nxa = &nxi->v6;
-+ struct nx_addr_v6 *old = NULL;
-+ int ret = 0;
-+
-+ spin_lock(&nxi->addr_lock);
-+ switch (type) {
-+/* case NXA_TYPE_ADDR:
-+ break; */
-+
-+ case NXA_TYPE_ANY:
-+ old = xchg(&nxa->next, NULL);
-+ memset(nxa, 0, sizeof(*nxa));
-+ break;
-+
-+ default:
-+ ret = -EINVAL;
-+ }
-+ spin_unlock(&nxi->addr_lock);
-+ __dealloc_nx_addr_v6_all(old);
-+ return ret;
-+}
-
- int vc_net_add_ipv6(struct nx_info *nxi, void __user *data)
- {
-@@ -831,10 +873,8 @@ int vc_net_remove_ipv6(struct nx_info *n
-
- switch (vc_data.type) {
- case NXA_TYPE_ANY:
-- __dealloc_nx_addr_v6_all(xchg(&nxi->v6.next, NULL));
-- memset(&nxi->v6, 0, sizeof(nxi->v6));
-+ do_remove_v6_addr(nxi, NULL, NULL, 0, vc_data.type, 0);
- break;
--
- default:
- return -EINVAL;
- }
---- linux-3.7/net/ipv6/netfilter/ip6t_MASQUERADE.c~ 2012-12-11 04:30:57.000000000 +0100
-+++ linux-3.7/net/ipv6/netfilter/ip6t_MASQUERADE.c 2012-12-13 21:09:30.741602424 +0100
-@@ -34,7 +34,7 @@