Skip navigation.
主页

IOCTL向内核传递参数

reachcool 的图片

/*********************************

*###此文中有引用别人的文章############

*###出处: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这个从用户空间向内核空间传递参数的函数,目前使用的可能不是很多,或者这个东西大家都比较明白,唯独我不大清楚,所以今天找了半天才弄到现在这个理解的层次,也不知道对不对。
希望大家指点!

晕~

coldiceangel 的图片

“而在我们的另外一

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

wheelz 的图片

用ioctl传递参数的情况

用ioctl传递参数的情况还是很多的,呵呵。

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

reachcool 的图片

关于前面那个vlan_ioctl

关于前面那个vlan_ioctl的情况
我也是抄的别人的,嘿嘿。
对于其正确与否,我开始也不大懂

我主要想理解的是后面的那个ioctl中的SIOCSIFBR命令
我在inet_ioctl中确实找到了关于它的case
是网桥的ioctl操作

我自己水平有限,只能理解到这个层次
还望大家多多指教才是

xiyang 的图片

为什么不采用netlink?

我觉得netlink机制要好用很多。

reachcool 的图片

netlink,其实正是我准

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