Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git] / kernel / vserver / network.c
index fbc1ad1..66e09de 100644 (file)
@@ -13,7 +13,6 @@
  *
  */
 
-#include <linux/config.h>
 #include <linux/slab.h>
 #include <linux/vserver/network_cmd.h>
 #include <linux/rcupdate.h>
@@ -205,7 +204,7 @@ static inline nid_t __nx_dynamic_id(void)
 /*     __create_nx_info()
 
        * create the requested context
-       * get() and hash it                             */
+       * get() and hash it                                     */
 
 static struct nx_info * __create_nx_info(int id)
 {
@@ -282,12 +281,12 @@ struct nx_info *create_nx_info(void)
 
 #endif
 
-/*     locate_nx_info()
+/*     lookup_nx_info()
 
        * search for a nx_info and get() it
        * negative id means current                             */
 
-struct nx_info *locate_nx_info(int id)
+struct nx_info *lookup_nx_info(int id)
 {
        struct nx_info *nxi = NULL;
 
@@ -393,36 +392,44 @@ out:
 }
 
 
+#ifdef CONFIG_INET
+
 #include <linux/netdevice.h>
 #include <linux/inetdevice.h>
 
-
 int ifa_in_nx_info(struct in_ifaddr *ifa, struct nx_info *nxi)
 {
        if (!nxi)
                return 1;
        if (!ifa)
                return 0;
-       return addr_in_nx_info(nxi, ifa->ifa_address);
+       return addr_in_nx_info(nxi, ifa->ifa_local);
 }
 
 int dev_in_nx_info(struct net_device *dev, struct nx_info *nxi)
 {
-       struct in_device *in_dev = __in_dev_get(dev);
-       struct in_ifaddr **ifap = NULL;
-       struct in_ifaddr *ifa = NULL;
+       struct in_device *in_dev;
+       struct in_ifaddr **ifap;
+       struct in_ifaddr *ifa;
+       int ret = 0;
 
        if (!nxi)
                return 1;
+
+       in_dev = in_dev_get(dev);
        if (!in_dev)
-               return 0;
+               goto out;
 
        for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL;
                ifap = &ifa->ifa_next) {
-               if (addr_in_nx_info(nxi, ifa->ifa_address))
-                       return 1;
+               if (addr_in_nx_info(nxi, ifa->ifa_local)) {
+                       ret = 1;
+                       break;
+               }
        }
-       return 0;
+       in_dev_put(in_dev);
+out:
+       return ret;
 }
 
 /*
@@ -434,7 +441,7 @@ int dev_in_nx_info(struct net_device *dev, struct nx_info *nxi)
 static inline int __addr_in_socket(struct sock *sk, uint32_t addr)
 {
        struct nx_info *nxi = sk->sk_nx_info;
-       uint32_t saddr = tcp_v4_rcv_saddr(sk);
+       uint32_t saddr = inet_rcv_saddr(sk);
 
        vxdprintk(VXD_CBIT(net, 5),
                "__addr_in_socket(%p,%d.%d.%d.%d) %p:%d.%d.%d.%d %p;%lx",
@@ -477,6 +484,18 @@ int nx_addr_conflict(struct nx_info *nxi, uint32_t addr, struct sock *sk)
        }
 }
 
+#endif /* CONFIG_INET */
+
+void nx_set_persistent(struct nx_info *nxi)
+{
+       if (nx_info_flags(nxi, NXF_PERSISTENT, 0)) {
+               get_nx_info(nxi);
+               claim_nx_info(nxi, current);
+       } else {
+               release_nx_info(nxi, current);
+               put_nx_info(nxi);
+       }
+}
 
 /* vserver syscall commands below here */
 
@@ -501,7 +520,7 @@ int vc_task_nid(uint32_t id, void __user *data)
                read_unlock(&tasklist_lock);
        }
        else
-               nid = current->nid;
+               nid = nx_current_nid();
        return nid;
 }
 
@@ -516,7 +535,7 @@ int vc_nx_info(uint32_t id, void __user *data)
        if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RESOURCE))
                return -EPERM;
 
-       nxi = locate_nx_info(id);
+       nxi = lookup_nx_info(id);
        if (!nxi)
                return -ESRCH;
 
@@ -554,6 +573,10 @@ int vc_net_create(uint32_t nid, void __user *data)
        /* initial flags */
        new_nxi->nx_flags = vc_data.flagword;
 
+       /* get a reference for persistent contexts */
+       if ((vc_data.flagword & NXF_PERSISTENT))
+               nx_set_persistent(new_nxi);
+
        vs_net_change(new_nxi, VSC_NETUP);
        ret = new_nxi->nx_id;
        nx_migrate_task(current, new_nxi);
@@ -570,7 +593,7 @@ int vc_net_migrate(uint32_t id, void __user *data)
        if (!capable(CAP_SYS_ADMIN))
                return -EPERM;
 
-       nxi = locate_nx_info(id);
+       nxi = lookup_nx_info(id);
        if (!nxi)
                return -ESRCH;
        nx_migrate_task(current, nxi);
@@ -599,7 +622,7 @@ int vc_net_add(uint32_t nid, void __user *data)
                break;
        }
 
-       nxi = locate_nx_info(nid);
+       nxi = lookup_nx_info(nid);
        if (!nxi)
                return -ESRCH;
 
@@ -641,11 +664,11 @@ int vc_net_remove(uint32_t nid, void __user *data)
        if (data && copy_from_user (&vc_data, data, sizeof(vc_data)))
                return -EFAULT;
 
-       nxi = locate_nx_info(nid);
+       nxi = lookup_nx_info(nid);
        if (!nxi)
                return -ESRCH;
 
-       switch (vc_data.type) {
+       switch ((unsigned)vc_data.type) {
        case NXA_TYPE_ANY:
                nxi->nbipv4 = 0;
                break;
@@ -667,7 +690,7 @@ int vc_get_nflags(uint32_t id, void __user *data)
        if (!capable(CAP_SYS_ADMIN))
                return -EPERM;
 
-       nxi = locate_nx_info(id);
+       nxi = lookup_nx_info(id);
        if (!nxi)
                return -ESRCH;
 
@@ -694,7 +717,7 @@ int vc_set_nflags(uint32_t id, void __user *data)
        if (copy_from_user (&vc_data, data, sizeof(vc_data)))
                return -EFAULT;
 
-       nxi = locate_nx_info(id);
+       nxi = lookup_nx_info(id);
        if (!nxi)
                return -ESRCH;
 
@@ -704,6 +727,9 @@ int vc_set_nflags(uint32_t id, void __user *data)
 
        nxi->nx_flags = vx_mask_flags(nxi->nx_flags,
                vc_data.flagword, mask);
+       if (trigger & NXF_PERSISTENT)
+               nx_set_persistent(nxi);
+
        put_nx_info(nxi);
        return 0;
 }
@@ -716,7 +742,7 @@ int vc_get_ncaps(uint32_t id, void __user *data)
        if (!capable(CAP_SYS_ADMIN))
                return -EPERM;
 
-       nxi = locate_nx_info(id);
+       nxi = lookup_nx_info(id);
        if (!nxi)
                return -ESRCH;
 
@@ -739,7 +765,7 @@ int vc_set_ncaps(uint32_t id, void __user *data)
        if (copy_from_user (&vc_data, data, sizeof(vc_data)))
                return -EFAULT;
 
-       nxi = locate_nx_info(id);
+       nxi = lookup_nx_info(id);
        if (!nxi)
                return -ESRCH;