This commit was manufactured by cvs2svn to create branch 'vserver'.
[linux-2.6.git] / kernel / vserver / legacynet.c
1
2 /*
3  *  linux/kernel/vserver/legacynet.c
4  *
5  *  Virtual Server: Legacy Network Funtions
6  *
7  *  Copyright (C) 2001-2003  Jacques Gelinas
8  *  Copyright (C) 2003-2005  Herbert Pƶtzl
9  *
10  *  V0.01  broken out from legacy.c
11  *
12  */
13
14 #include <linux/config.h>
15 #include <linux/sched.h>
16 #include <linux/vs_context.h>
17 #include <linux/vs_network.h>
18 #include <linux/vserver/legacy.h>
19 #include <linux/vserver/namespace.h>
20 #include <linux/namespace.h>
21
22 #include <asm/errno.h>
23 #include <asm/uaccess.h>
24
25
26 extern struct nx_info *create_nx_info(void);
27
28 /*  set ipv4 root (syscall) */
29
30 int vc_set_ipv4root(uint32_t nbip, void __user *data)
31 {
32         int i, err = -EPERM;
33         struct vcmd_set_ipv4root_v3 vc_data;
34         struct nx_info *new_nxi, *nxi = current->nx_info;
35
36         if (nbip < 0 || nbip > NB_IPV4ROOT)
37                 return -EINVAL;
38         if (copy_from_user (&vc_data, data, sizeof(vc_data)))
39                 return -EFAULT;
40
41         if (!nxi || nxi->ipv4[0] == 0 || capable(CAP_NET_ADMIN))
42                 // We are allowed to change everything
43                 err = 0;
44         else if (nxi) {
45                 int found = 0;
46
47                 // We are allowed to select a subset of the currently
48                 // installed IP numbers. No new one allowed
49                 // We can't change the broadcast address though
50                 for (i=0; i<nbip; i++) {
51                         int j;
52                         __u32 nxip = vc_data.nx_mask_pair[i].ip;
53                         for (j=0; j<nxi->nbipv4; j++) {
54                                 if (nxip == nxi->ipv4[j]) {
55                                         found++;
56                                         break;
57                                 }
58                         }
59                 }
60                 if ((found == nbip) &&
61                         (vc_data.broadcast == nxi->v4_bcast))
62                         err = 0;
63         }
64         if (err)
65                 return err;
66
67         new_nxi = create_nx_info();
68         if (!new_nxi)
69                 return -EINVAL;
70
71         new_nxi->nbipv4 = nbip;
72         for (i=0; i<nbip; i++) {
73                 new_nxi->ipv4[i] = vc_data.nx_mask_pair[i].ip;
74                 new_nxi->mask[i] = vc_data.nx_mask_pair[i].mask;
75         }
76         new_nxi->v4_bcast = vc_data.broadcast;
77         // current->nx_info = new_nxi;
78         if (nxi) {
79                 printk("!!! switching nx_info %p->%p\n", nxi, new_nxi);
80                 clr_nx_info(&current->nx_info);
81         }
82         nx_migrate_task(current, new_nxi);
83         // set_nx_info(&current->nx_info, new_nxi);
84         // current->nid = new_nxi->nx_id;
85         put_nx_info(new_nxi);
86         return 0;
87 }
88
89