转:http://blog.csdn.net/nerdx/article/details/12223489
-
-
-
-
-
-
-
-
-
-
-
1.1 static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg)
-
{
-
...
-
case SIOCGIFBR:
-
case SIOCSIFBR:
-
case SIOCBRADDBR:
-
case SIOCBRDELBR:
-
err = -ENOPKG;
-
if (!br_ioctl_hook)
-
request_module("bridge");
-
-
down(&br_ioctl_mutex);
-
if (br_ioctl_hook)
-
err = br_ioctl_hook(cmd, argp);
-
up(&br_ioctl_mutex);
-
break;
-
...
-
}
-
-
-
-
1.2 int br_ioctl_deviceless_stub(unsigned int cmd, void __user *uarg)
-
{
-
switch (cmd) {
-
case SIOCGIFBR:
-
case SIOCSIFBR:
-
return old_deviceless(uarg);
-
-
case SIOCBRADDBR:
-
case SIOCBRDELBR:
-
{
-
char buf[IFNAMSIZ];
-
-
if (!capable(CAP_NET_ADMIN))
-
return -EPERM;
-
-
if (copy_from_user(buf, uarg, IFNAMSIZ))
-
return -EFAULT;
-
-
buf[IFNAMSIZ-1] = 0;
-
if (cmd == SIOCBRADDBR)
-
return br_add_bridge(buf);
-
-
return br_del_bridge(buf);
-
}
-
}
-
return -EOPNOTSUPP;
-
}
-
-
-
-
-
1.3 static int old_deviceless(void __user *uarg)
-
{
-
unsigned long args[3];
-
-
if (copy_from_user(args, uarg, sizeof(args)))
-
return -EFAULT;
-
-
switch (args[0]) {
-
case BRCTL_GET_VERSION:
-
return BRCTL_VERSION;
-
-
case BRCTL_GET_BRIDGES:
-
{
-
int *indices;
-
int ret = 0;
-
-
indices = kmalloc(args[2]*sizeof(int), GFP_KERNEL);
-
if (indices == NULL)
-
return -ENOMEM;
-
-
memset(indices, 0, args[2]*sizeof(int));
-
args[2] = get_bridge_ifindices(indices, args[2]);
-
-
ret = copy_to_user((void __user *)args[1], indices, args[2]*sizeof(int))
-
? -EFAULT : args[2];
-
-
kfree(indices);
-
return ret;
-
}
-
-
case BRCTL_ADD_BRIDGE:
-
case BRCTL_DEL_BRIDGE:
-
{
-
char buf[IFNAMSIZ];
-
-
if (!capable(CAP_NET_ADMIN))
-
return -EPERM;
-
-
if (copy_from_user(buf, (void __user *)args[1], IFNAMSIZ))
-
return -EFAULT;
-
-
buf[IFNAMSIZ-1] = 0;
-
-
if (args[0] == BRCTL_ADD_BRIDGE)
-
return br_add_bridge(buf);
-
-
return br_del_bridge(buf);
-
}
-
}
-
-
return -EOPNOTSUPP;
-
}
-
-
-
-
-
-
-
2.1 int br_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
-
{
-
struct net_bridge *br = netdev_priv(dev);
-
-
switch(cmd) {
-
case SIOCDEVPRIVATE:
-
return old_dev_ioctl(dev, rq, cmd);
-
-
case SIOCBRADDIF:
-
case SIOCBRDELIF:
-
return add_del_if(br, rq->ifr_ifindex, cmd == SIOCBRADDIF);
-
-
}
-
-
pr_debug("Bridge does not support ioctl 0x%x\n", cmd);
-
return -EOPNOTSUPP;
-
}
-
-
-
-
-
2.2 static int old_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
-
{
-
struct net_bridge *br = netdev_priv(dev);
-
unsigned long args[4];
-
-
if (copy_from_user(args, rq->ifr_data, sizeof(args)))
-
return -EFAULT;
-
-
switch (args[0]) {
-
case BRCTL_ADD_IF:
-
case BRCTL_DEL_IF:
-
return add_del_if(br, args[1], args[0] == BRCTL_ADD_IF);
-
-
case BRCTL_GET_BRIDGE_INFO:
-
{
-
struct __bridge_info b;
-
-
...
-
-
if (copy_to_user((void __user *)args[1], &b, sizeof(b)))
-
return -EFAULT;
-
-
return 0;
-
}
-
-
case BRCTL_GET_PORT_LIST:
-
{
-
int num, *indices;
-
...
-
-
get_port_ifindices(br, indices, num);
-
if (copy_to_user((void __user *)args[1], indices, num*sizeof(int)))
-
num = -EFAULT;
-
kfree(indices);
-
return num;
-
}
-
-
case BRCTL_SET_BRIDGE_FORWARD_DELAY:
-
if (!capable(CAP_NET_ADMIN))
-
return -EPERM;
-
-
spin_lock_bh(&br->lock);
-
br->bridge_forward_delay = clock_t_to_jiffies(args[1]);
-
if (br_is_root_bridge(br))
-
br->forward_delay = br->bridge_forward_delay;
-
spin_unlock_bh(&br->lock);
-
return 0;
-
-
case BRCTL_SET_BRIDGE_HELLO_TIME:
-
if (!capable(CAP_NET_ADMIN))
-
return -EPERM;
-
-
spin_lock_bh(&br->lock);
-
br->bridge_hello_time = clock_t_to_jiffies(args[1]);
-
if (br_is_root_bridge(br))
-
br->hello_time = br->bridge_hello_time;
-
spin_unlock_bh(&br->lock);
-
return 0;
-
-
case BRCTL_SET_BRIDGE_MAX_AGE:
-
if (!capable(CAP_NET_ADMIN))
-
return -EPERM;
-
-
spin_lock_bh(&br->lock);
-
br->bridge_max_age = clock_t_to_jiffies(args[1]);
-
if (br_is_root_bridge(br))
-
br->max_age = br->bridge_max_age;
-
spin_unlock_bh(&br->lock);
-
return 0;
-
-
case BRCTL_SET_AGEING_TIME:
-
if (!capable(CAP_NET_ADMIN))
-
return -EPERM;
-
-
br->ageing_time = clock_t_to_jiffies(args[1]);
-
return 0;
-
-
case BRCTL_GET_PORT_INFO:
-
{
-
struct __port_info p;
-
struct net_bridge_port *pt;
-
-
rcu_read_lock();
-
if ((pt = br_get_port(br, args[2])) == NULL) {
-
rcu_read_unlock();
-
return -EINVAL;
-
}
-
....
-
rcu_read_unlock();
-
-
if (copy_to_user((void __user *)args[1], &p, sizeof(p)))
-
return -EFAULT;
-
-
return 0;
-
}
-
-
case BRCTL_SET_BRIDGE_STP_STATE:
-
if (!capable(CAP_NET_ADMIN))
-
return -EPERM;
-
-
br->stp_enabled = args[1]?1:0;
-
return 0;
-
-
case BRCTL_SET_BRIDGE_PRIORITY:
-
if (!capable(CAP_NET_ADMIN))
-
return -EPERM;
-
-
spin_lock_bh(&br->lock);
-
br_stp_set_bridge_priority(br, args[1]);
-
spin_unlock_bh(&br->lock);
-
return 0;
-
-
case BRCTL_SET_PORT_PRIORITY:
-
{
-
struct net_bridge_port *p;
-
int ret = 0;
-
-
if (!capable(CAP_NET_ADMIN))
-
return -EPERM;
-
-
if (args[2] >= (1<<(16-BR_PORT_BITS)))
-
return -ERANGE;
-
-
spin_lock_bh(&br->lock);
-
if ((p = br_get_port(br, args[1])) == NULL)
-
ret = -EINVAL;
-
else
-
br_stp_set_port_priority(p, args[2]);
-
spin_unlock_bh(&br->lock);
-
return ret;
-
}
-
-
case BRCTL_SET_PATH_COST:
-
{
-
struct net_bridge_port *p;
-
int ret = 0;
-
-
if (!capable(CAP_NET_ADMIN))
-
return -EPERM;
-
-
spin_lock_bh(&br->lock);
-
if ((p = br_get_port(br, args[1])) == NULL)
-
ret = -EINVAL;
-
else
-
br_stp_set_path_cost(p, args[2]);
-
spin_unlock_bh(&br->lock);
-
return ret;
-
}
-
-
case BRCTL_GET_FDB_ENTRIES:
-
return get_fdb_entries(br, (void __user *)args[1],
-
args[2], args[3]);
-
}
-
-
return -EOPNOTSUPP;
-
}
-
阅读(711) | 评论(0) | 转发(0) |