免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1579 | 回复: 2
打印 上一主题 下一主题

请教内核中队列编程的问题? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2006-04-12 11:00 |只看该作者 |倒序浏览
各位高手及楼主:
最近我在作一个课题,想用netfilter来实现如下功能
(1) 利用netfilter中的hook来获取数据,并根据数据的优先级进行排队,然后返回NF_QUEUE;
(2) 利用nf_register_queue_handler()函数来注册一个函数,该函数是对队列进行调度;
现在的问题是:
(1) 由于是两个内核模块,调度程序如何从前面模块实现的队列中读取相应数据?
(2)若我的设计思想有问题,请指正!

论坛徽章:
0
2 [报告]
发表于 2006-04-12 11:03 |只看该作者
>(1) 由于是两个内核模块,调度程序如何从前面模块实现的队列中读取相应数据?
netfilter得等其他朋友帮忙(偶不懂). 可以一个模块定义全局的list, 再EXPORT_SYMBOL,另一个就可以用了。

论坛徽章:
0
3 [报告]
发表于 2006-04-13 12:24 |只看该作者

回复 2楼 albcamus 的帖子

谢谢你的回复,由于我刚刚开始进行内核编程,所以,请你帮我解决如下问题:
在nfqueue.c中用EXPORT_SYMBOL定义了__dequeue和cbq符号,并且加载后用ksyms可以看到该符号,但在queue_m.c中调用时,加载后出现: unresolved symbol cbq和unresolved symbol __dequeue.
为什么会出现该问题?
我的程序如下:
/* nfqueue.c */
#define __KERNEL__
#define MODULE
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/kernel.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>
#include <linux/skbuff.h>
#include <linux/config.h>
#include <net/ip.h>
#include <linux/inet.h>

static struct nf_hook_ops nfho_pre;

struct data_class_head {
        unsigned int qlen;
        struct data_class        *next;               
        struct data_class        *prev;

};
struct data_class {
        struct data_class *next;
        struct sk_buff *data;
};

struct data_class_head *cbq;

EXPORT_SYMBOL( cbq );

int queue_empty(struct data_class_head *list)
{
        return (list->next == (struct data_class *) list);
}
void __queue_init(struct data_class_head *list)
{
        printk("Enter queue_init\n";
        list->prev = list->next = NULL;
        list->qlen = 0;
}
void __queue_head(struct data_class_head *list, struct sk_buff *newskb)
{
        struct data_class *newptr;
        printk("Enter queue_head function \n";
        newptr = (struct data_class *)kmalloc(sizeof(struct data_class ),GFP_KERNEL);
      
        newptr->data = newskb;
        newptr->next = NULL;
        list->qlen++;      
        if( list->next == NULL )
        {
                list->next = list->prev = newptr;
        }
        else
                list->next = (list->next)->next = newptr;
}

struct sk_buff *__dequeue(struct data_class_head *list)
{
        struct data_class *result;

        if( list->prev == NULL )
        {
                printk("queue is null...\n";
                return NULL;
        }
        result = list->prev;
        list->prev = result->next;
        list->qlen--;
        if( list->prev == NULL )谢谢你的回复,由于我刚刚开始进行内核编程,所以,请你帮我解决如下问题:
在nfqueue.c中用EXPORT_SYMBOL定义了__dequeue和cbq符号,并且加载后用ksyms可以看到该符号,但在queue_m.c中调用时,加载后出现: unresolved symbol cbq和unresolved symbol __dequeue.
为什么会出现该问题?
我的程序如下:
/* nfqueue.c */
#define __KERNEL__
#define MODULE
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/kernel.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>
#include <linux/skbuff.h>
#include <linux/config.h>
#include <net/ip.h>
#include <linux/inet.h>

static struct nf_hook_ops nfho_pre;

struct data_class_head {
        unsigned int qlen;
        struct data_class        *next;               
        struct data_class        *prev;

};
struct data_class {
        struct data_class *next;
        struct sk_buff *data;
};

struct data_class_head *cbq;

EXPORT_SYMBOL( cbq );

int queue_empty(struct data_class_head *list)
{
        return (list->next == (struct data_class *) list);
}
void __queue_init(struct data_class_head *list)
{
        printk("Enter queue_init\n";
        list->prev = list->next = NULL;
        list->qlen = 0;
}
void __queue_head(struct data_class_head *list, struct sk_buff *newskb)
{
        struct data_class *newptr;
        printk("Enter queue_head function \n";
        newptr = (struct data_class *)kmalloc(sizeof(struct data_class ),GFP_KERNEL);
      
        newptr->data = newskb;
        newptr->next = NULL;
        list->qlen++;      
        if( list->next == NULL )
        {
                list->next = list->prev = newptr;
        }
        else
                list->next = (list->next)->next = newptr;
}

struct sk_buff *__dequeue(struct data_class_head *list)
{
        struct data_class *result;

        if( list->prev == NULL )
        {
                printk("queue is null...\n";
                return NULL;
        }
        result = list->prev;
        list->prev = result->next;
        list->qlen--;
        if( list->prev == NULL )
                list->next = NULL;
        kfree(result);
        return (result->data);
}

EXPORT_SYMBOL(__dequeue );

unsigned int hook_pre_routing( unsigned int hooknum,
                struct sk_buff **skb,
                const struct net_device *in,
                const struct net_device *out,
                int (*okfn)(struct sk_buff *))
{
        printk("Enter NF_IP_PRE_ROUTING  ...\n";
        if((*skb)->nh.iph->saddr == in_aton("210.27.5.64" )
        {
                struct sk_buff *newskb;
                printk("Get message ...\n";

                newskb = kmalloc(sizeof(struct data_class_head),GFP_KERNEL);      
                //newskb->priority = 2;
                newskb = *skb;
                __queue_head(cbq,newskb);      
                              
                //return NF_ACCEPT;
                return NF_QUEUE;
        }
        else
                return NF_ACCEPT;
}

int init_module()
{
        //struct data_class_head *q;
        nfho_pre.hook = hook_pre_routing;
        nfho_pre.hooknum = NF_IP_PRE_ROUTING;
        nfho_pre.pf = PF_INET;
        nfho_pre.priority = NF_IP_PRI_FIRST;

        nf_register_hook( &nfho_pre );

        cbq = (struct data_class_head *)kmalloc(sizeof(struct data_class_head),GFP_KERNEL);      
        __queue_init(cbq);
        return 0;
}

void cleanup_module()
{
        nf_unregister_hook( &nfho_pre );
}

MODULE_LICENSE("GPL";


/*
* queue_m.c      
*
*/
#define __KERNEL__
#define MODULE
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/kernel.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>
#include <linux/skbuff.h>
#include <linux/config.h>
#include <linux/types.h>

extern struct data_class_head *cbq;
extern struct sk_buff *__dequeue( struct data_class_head *list);

static int cbwfq_queue( struct sk_buff *skb, struct nf_info *info, void *data)
{
        printk("Enter CBWFQ_QUEUE ...\n";

        skb = __dequeue( cbq );
        kfree(info);
        nf_reinject(skb,info, NF_ACCEPT);      
        return 0;
}

int init_module()
{
        nf_register_queue_handler(PF_INET, NULL, NULL );
        if(nf_register_queue_handler(PF_INET, cbwfq_queue, NULL ) < 0 )
        {
                printk("Register queue error !\n";
                return -1;
        }
      
        return 0;
}

void cleanup_module()
{
        nf_unregister_queue_handler(PF_INET);
}

MODULE_LICENSE("GPL";
                list->next = NULL;
        kfree(result);
        return (result->data);
}

EXPORT_SYMBOL(__dequeue );

unsigned int hook_pre_routing( unsigned int hooknum,
                struct sk_buff **skb,
                const struct net_device *in,
                const struct net_device *out,
                int (*okfn)(struct sk_buff *))
{
        printk("Enter NF_IP_PRE_ROUTING  ...\n";
        if((*skb)->nh.iph->saddr == in_aton("210.27.5.64" )
        {
                struct sk_buff *newskb;
                printk("Get message ...\n";

                newskb = kmalloc(sizeof(struct data_class_head),GFP_KERNEL);      
                //newskb->priority = 2;
                newskb = *skb;
                __queue_head(cbq,newskb);      
                              
                //return NF_ACCEPT;
                return NF_QUEUE;
        }
        else
                return NF_ACCEPT;
}

int init_module()
{
        //struct data_class_head *q;
        nfho_pre.hook = hook_pre_routing;
        nfho_pre.hooknum = NF_IP_PRE_ROUTING;
        nfho_pre.pf = PF_INET;
        nfho_pre.priority = NF_IP_PRI_FIRST;

        nf_register_hook( &nfho_pre );

        cbq = (struct data_class_head *)kmalloc(sizeof(struct data_class_head),GFP_KERNEL);      
        __queue_init(cbq);
        return 0;
}

void cleanup_module()
{
        nf_unregister_hook( &nfho_pre );
}

MODULE_LICENSE("GPL";


/*
* queue_m.c      
*
*/
#define __KERNEL__
#define MODULE
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/kernel.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>
#include <linux/skbuff.h>
#include <linux/config.h>
#include <linux/types.h>

extern struct data_class_head *cbq;
extern struct sk_buff *__dequeue( struct data_class_head *list);

static int cbwfq_queue( struct sk_buff *skb, struct nf_info *info, void *data)
{
        printk("Enter CBWFQ_QUEUE ...\n";

        skb = __dequeue( cbq );
        kfree(info);
        nf_reinject(skb,info, NF_ACCEPT);      
        return 0;
}

int init_module()
{
        nf_register_queue_handler(PF_INET, NULL, NULL );
        if(nf_register_queue_handler(PF_INET, cbwfq_queue, NULL ) < 0 )
        {
                printk("Register queue error !\n";
                return -1;
        }
      
        return 0;
}

void cleanup_module()
{
        nf_unregister_queue_handler(PF_INET);
}

MODULE_LICENSE("GPL";
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP