*
*/
-#include <linux/config.h>
#include <linux/slab.h>
#include <linux/vserver/network_cmd.h>
#include <linux/rcupdate.h>
/* __create_nx_info()
* create the requested context
- * get() and hash it */
+ * get() and hash it */
static struct nx_info * __create_nx_info(int id)
{
#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;
}
+#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;
}
/*
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",
}
}
+#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 */
read_unlock(&tasklist_lock);
}
else
- nid = current->nid;
+ nid = nx_current_nid();
return nid;
}
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;
/* 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);
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);
break;
}
- nxi = locate_nx_info(nid);
+ nxi = lookup_nx_info(nid);
if (!nxi)
return -ESRCH;
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;
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
- nxi = locate_nx_info(id);
+ nxi = lookup_nx_info(id);
if (!nxi)
return -ESRCH;
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;
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;
}
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
- nxi = locate_nx_info(id);
+ nxi = lookup_nx_info(id);
if (!nxi)
return -ESRCH;
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;