IOCTL向内核传递参数

/*********************************
*###此文中有引用别人的文章############
*###出处:http://www.cublog.cn/opera/showart.php?blogid=21968&id=144911
*###正是这段文章帮助我有了后面的理解
********************************/
//begiin
一、应用层
uint16 data16;
if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf("socket failed\n\r");
}
if(ioctl(fd, SIOCSIFVLAN_PVID_PRI, &data16) < 0)
{
printf("ioctl pvid failed\n\r");
}
二、linux内核
1、 在sockios.h中定义
#define SIOCSIFVLAN_PVID_PRI 0x8985 /* Set 802.1Q VLAN pvid */
2、在af_inet.c中
添加
extern int VLAN1QEN(unsigned int ,void *arg);
在inet_ioctl()函数中添加
case SIOCSIFVLAN_PVID_PRI:
return VLAN1QEN(cmd, arg);
3、另外定义:
static unsigned int VLAN_PVID_PRI = 0;
int VLAN1QEN(unsigned int cmd,void *arg)
{
unsigned int data;
if (copy_from_user(&data, arg, sizeof(int)))
return -EFAULT;
switch (cmd) {
case SIOCSIFVLAN_PVID_PRI:
VLAN_PVID_PRI = data;
break;
default:
return -EINVAL;
}
}
//end
其实,这个问题却是困扰了我很久
在copy_from_user()和copy_to_user()的过程中,使用了arg这个参数指向用户空间某命令参数,在用户空间使用ioctl(int fd,int cmd, *bcf)想内核空间传递这个参数
这里,我实在找不到bcf和arg的联系。
通过半天多的查找翻阅,终于在http://www.cublog.cn/opera/showart.php?blogid=21968&id=144911找到了这篇短文,解开了我的疑惑。
这里我把我的理解写在这里:
首先,ioctl的功能我就不说了,网上比较多,大致是用来控制IO的。
其次,第一个参数fd是一个文件描述符,我们这里是建立的一个套接字描述符
再次,第二个参数,是在sockios.h中定义的一个32位描述符,我们也可以在这里添加新的类型,用来扩展实际需求。
最后,第三个参数,是一个指针,用来指向某些我们实际应用中的参数。
在af_inet.c中的inet_ioctl()函数中的switch——case中,对上面第二个参数分别进行了描述。
例如我所需要的是这样的一个类型:
ioctl( fd, SIOCSIFBR, &bcf )
在inet_ioctl()函数中如下表示: Linux/net/ipv4/af_inet.c
int inet_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
switch (cmd)
{……
case SIOCGIFBR:
case SIOCSIFBR:
#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
#ifdef CONFIG_KMOD
if (br_ioctl_hook == NULL)
request_module("bridge");
#endif
if (br_ioctl_hook != NULL)
return br_ioctl_hook(arg);
879 #endif
return -ENOPKG;
……
}//switch end here
这里inet_ioctl()中的第三个参数arg,正好对应在ioctl中的的三个参数&bcf,其实,inet_ioctl属于ioctl在linux内核中的网络设备ioctl的底层函数,用来处理网络设备的一些IO操作。
上面的一小段程序显示,我们用户层ioctl函数中的第三个参数对应在br_ioctl_hook(arg)中的arg上。
而在我们的另外一个函数中定义了一个函数叫br_ioctl(arg)函数,并且其中使用了copy_to_user 和copy_from_user 用来将用户层中ioctl函数传下来的 命令在内核中进行相应的处理。最后,用一句:br_ioctl_hook = br_ioctl 将这个函数送进inet_ioctl中。
这里我才明白,我一直想要弄懂的东西
ioctl —— br_ioctl之间的关系
ioctl这个从用户空间向内核空间传递参数的函数,目前使用的可能不是很多,或者这个东西大家都比较明白,唯独我不大清楚,所以今天找了半天才弄到现在这个理解的层次,也不知道对不对。
希望大家指点!
晕~

用ioctl传递参数的情况
用ioctl传递参数的情况还是很多的,呵呵。
你这里设置的vlan pvid应该是属于physical port的属性,
因此不应该在inet_ioctl里面直接处理。应该直接由vlan device
处理,应该扩展vlan_dev_ioctl(),这样也不需要修改多处内核。

关于前面那个vlan_ioctl
关于前面那个vlan_ioctl的情况
我也是抄的别人的,嘿嘿。
对于其正确与否,我开始也不大懂
我主要想理解的是后面的那个ioctl中的SIOCSIFBR命令
我在inet_ioctl中确实找到了关于它的case
是网桥的ioctl操作
我自己水平有限,只能理解到这个层次
还望大家多多指教才是

netlink,其实正是我准
netlink,其实正是我准备要用的
上面我说的那些,都是我在看别人的代码中发现的我不懂的问题
呵呵。

“而在我们的另外一
“而在我们的另外一个函数(哪个函数?)中定义了一个函数叫br_ioctl(arg)函数,并且其中使用了copy_to_user 和copy_from_user 用来将用户层中ioctl函数传下来的命令在内核中进行相应的处理。最后,用一句:br_ioctl_hook = br_ioctl 将这个函数送进inet_ioctl中(???)。”---这一段是什么意思?