return rc;
}
+/*
+ Check that a device is not member of the ipv4root assigned to the process
+ Return true if this is the case
-int devinet_ioctl(unsigned int cmd, void *arg)
+ If the process is not bound to specific IP, then it returns 0 (all
+ interface are fine).
+*/
+static inline int devinet_notiproot (struct in_ifaddr *ifa)
+{
+ int ret = 0;
+ struct nx_info *nxi;
+
+ if ((nxi = current->nx_info)) {
+ int i;
+ int nbip = nxi->nbipv4;
+ __u32 addr = ifa->ifa_local;
+ ret = 1;
+ for (i=0; i<nbip; i++) {
+ if(nxi->ipv4[i] == addr) {
+ ret = 0;
+ break;
+ }
+ }
+ }
+ return ret;
+}
+
+
+int devinet_ioctl(unsigned int cmd, void __user *arg)
{
struct ifreq ifr;
struct sockaddr_in sin_orig;
ret = -EADDRNOTAVAIL;
if (!ifa && cmd != SIOCSIFADDR && cmd != SIOCSIFFLAGS)
goto done;
+ if (!ifa_in_nx_info(ifa, current->nx_info))
+ goto done;
switch(cmd) {
case SIOCGIFADDR: /* Get interface address */
inet_del_ifa(in_dev, ifap, 0);
ifa->ifa_mask = sin->sin_addr.s_addr;
ifa->ifa_prefixlen = inet_mask_len(ifa->ifa_mask);
+
+ /* See if current broadcast address matches
+ * with current netmask, then recalculate
+ * the broadcast address. Otherwise it's a
+ * funny address, so don't touch it since
+ * the user seems to know what (s)he's doing...
+ */
+ if ((dev->flags & IFF_BROADCAST) &&
+ (ifa->ifa_prefixlen < 31) &&
+ (ifa->ifa_broadcast ==
+ (ifa->ifa_local|~ifa->ifa_mask))) {
+ ifa->ifa_broadcast = (ifa->ifa_local |
+ ~sin->sin_addr.s_addr);
+ }
inet_insert_ifa(ifa);
}
break;
goto out;
}
-static int inet_gifconf(struct net_device *dev, char *buf, int len)
+static int inet_gifconf(struct net_device *dev, char __user *buf, int len)
{
struct in_device *in_dev = __in_dev_get(dev);
struct in_ifaddr *ifa;
goto out;
for (; ifa; ifa = ifa->ifa_next) {
+ if (!ifa_in_nx_info(ifa, current->nx_info))
+ continue;
if (!buf) {
done += sizeof(ifr);
continue;
read_lock(&in_dev->lock);
for (ifa = in_dev->ifa_list, ip_idx = 0; ifa;
ifa = ifa->ifa_next, ip_idx++) {
+ if (!ifa_in_nx_info(ifa, current->nx_info))
+ continue;
if (ip_idx < s_ip_idx)
continue;
if (inet_fill_ifaddr(skb, ifa, NETLINK_CB(cb->skb).pid,
}
static int devinet_sysctl_forward(ctl_table *ctl, int write,
- struct file* filp, void *buffer,
- size_t *lenp)
+ struct file* filp, void __user *buffer,
+ size_t *lenp, loff_t *ppos)
{
int *valp = ctl->data;
int val = *valp;
- int ret = proc_dointvec(ctl, write, filp, buffer, lenp);
+ int ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos);
if (write && *valp != val) {
if (valp == &ipv4_devconf.forwarding)
}
int ipv4_doint_and_flush(ctl_table *ctl, int write,
- struct file* filp, void *buffer,
- size_t *lenp)
+ struct file* filp, void __user *buffer,
+ size_t *lenp, loff_t *ppos)
{
int *valp = ctl->data;
int val = *valp;
- int ret = proc_dointvec(ctl, write, filp, buffer, lenp);
+ int ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos);
if (write && *valp != val)
rt_cache_flush(0);
return ret;
}
-int ipv4_doint_and_flush_strategy(ctl_table *table, int *name, int nlen,
- void *oldval, size_t *oldlenp,
- void *newval, size_t newlen,
+int ipv4_doint_and_flush_strategy(ctl_table *table, int __user *name, int nlen,
+ void __user *oldval, size_t __user *oldlenp,
+ void __user *newval, size_t newlen,
void **context)
{
int *valp = table->data;
if (newlen != sizeof(int))
return -EINVAL;
- if (get_user(new, (int *)newval))
+ if (get_user(new, (int __user *)newval))
return -EFAULT;
if (new == *valp)