- 论坛徽章:
- 0
|
原帖由 mq110 于 2005-12-7 12:42 发表
内核进程和用户进程 共享内存了 你如何实现互斥???
你说的<<Unix环境高级编程>>只是提到了System V 共享内存的方式。他是用户态的。。不是我说的内核进程和用户进程共享内存的方式。
可能我误解你的意思了!
但是偶认为,包过滤函数与用户空间操作函数之间共享规则:
1、可以通过共享空间来完成的,在Win下边做防火墙,偶就是这样子做的;至于linux下内核与用户进程共享内存的互斥,到是没有做过。实现不行,用最笨的方法,自己实现互斥锁应该是可以的吧,回头我做做测试先。
2、netfilter在实现的时候,应该是使用 find_table_lock来实现的,不过偶没有认真地跟下去看这个函数了。如果我没有分析错的话,iptables通过调用setsockopt函数,进过层层调用,最后是
nf_sockopts(),它事实上是操作了:
static struct nf_sockopt_ops ipt_sockopts
= { { NULL, NULL }, PF_INET, IPT_BASE_CTL, IPT_SO_SET_MAX+1, do_ipt_set_ctl,
IPT_BASE_CTL, IPT_SO_GET_MAX+1, do_ipt_get_ctl, 0, NULL };
因为在这个结构中,封装了set/get函数。比如get,它把内核空间的规则拷贝到用户这间:
static int
do_ipt_get_ctl(struct sock *sk, int cmd, void *user, int *len)
……
case IPT_SO_GET_ENTRIES: {
struct ipt_get_entries get;
if (*len < sizeof(get)) {
duprintf("get_entries: %u < %u\n", *len, sizeof(get));
ret = -EINVAL;
} else if (copy_from_user(&get, user, sizeof(get)) != 0) {
ret = -EFAULT;
} else if (*len != sizeof(struct ipt_get_entries) + get.size) {
duprintf("get_entries: %u != %u\n", *len,
sizeof(struct ipt_get_entries) + get.size);
ret = -EINVAL;
} else
ret = get_entries(&get, user);
break;
}
进入get_entries
static int
get_entries(const struct ipt_get_entries *entries,
struct ipt_get_entries *uptr)
{
int ret;
struct ipt_table *t;
t = find_table_lock(entries->name, &ret, &ipt_mutex);
if (t) {
duprintf("t->private->number = %u\n",
t->private->number);
if (entries->size == t->private->size)
ret = copy_entries_to_user(t->private->size,
t, uptr->entrytable);
else {
duprintf("get_entries: I've got %u not %u!\n",
t->private->size,
entries->size);
ret = -EINVAL;
}
up(&ipt_mutex);
} else
duprintf("get_entries: Can't find %s!\n",
entries->name);
return ret;
}
find_table_lock用于返回查找的表的元素,同时第三个参数应该即为互斥锁,应该就是你所关心的。不过前一遍看它时并没有仔细地分析它。我看完第二遍的时候,或许可以写个详尽的分析出来。
[ 本帖最后由 独孤九贱 于 2005-12-7 13:16 编辑 ] |
|