Chinaunix首页 | 论坛 | 博客
  • 博客访问: 125798
  • 博文数量: 42
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 354
  • 用 户 组: 普通用户
  • 注册时间: 2014-07-01 15:34
个人简介

不晓得说啥子

文章分类

全部博文(42)

文章存档

2015年(41)

2014年(1)

我的朋友

分类: LINUX

2015-04-03 15:04:28

大概流程如下(以filter表注册钩子函数为例):

iptable_filter.c
     |
     |
iptable_filter_init()     先初始化相应的表,再注册钩子函数                                                             
     |
     |
xt_hook_link( & packet_filter, iptable_filter_hook)   
     |
     |
nf_register_hooks( *ops)
     |
     |
nf_register_hook( ops[i])

1、iptables_filter_init(){

               首先注册标的一些信息,这个在下一节在细讲
     ret = register_pernet_subsys(&iptable_filter_net_ops);
     if (ret < 0)
          return ret;

     /* Register hooks */
然后再注册hook钩子函数到相应的钩子点
     filter_ops = xt_hook_link(&packet_filter, iptable_filter_hook);
     if (IS_ERR(filter_ops)) {
          ret = PTR_ERR(filter_ops);
          unregister_pernet_subsys(&iptable_filter_net_ops);
     }
}
2、struct nf_hook_ops *xt_hook_link(const struct xt_table *table, nf_hookfn *fn)
{
     unsigned int hook_mask = table->valid_hooks;
     uint8_t i, num_hooks = hweight32(hook_mask);
     uint8_t hooknum;
     struct nf_hook_ops *ops;
     int ret;
     ops = kmalloc(sizeof(*ops) * num_hooks, GFP_KERNEL);
     if (ops == NULL)
          return ERR_PTR(-ENOMEM);
     
从表中的hookmask中得到该表在哪些钩子点需要注册钩子函数
然后再用该表的信息生成相应个数的nf_hook_ops结构,在调用nf_register_hooks(ops,num_hooks)             
     for (i = 0, hooknum = 0; i < num_hooks && hook_mask != 0;
          hook_mask >>= 1, ++hooknum) {
          if (!(hook_mask & 1))
               continue;
          ops[i].hook     = fn;
          ops[i].owner    = table->me;
          ops[i].pf       = table->af;
          ops[i].hooknum  = hooknum;
          ops[i].priority = table->priority;
          ++i;

     }
     ret = nf_register_hooks(ops, num_hooks);
     if (ret < 0) {
          kfree(ops);
          return ERR_PTR(ret);
     }
     return ops;
}

3、
int nf_register_hooks(struct nf_hook_ops *reg, unsigned int n) 直接对每一个nf_hook_ops结构调用nf_register_hook( )
{
     unsigned int i;
     int err = 0;

     for (i = 0; i < n; i++) {
          err = nf_register_hook(®[i]);
          if (err)
               goto err;
     }
     return err;

err:
     if (i > 0)
          nf_unregister_hooks(reg, i);
     return err;
}

4、int nf_register_hook(struct nf_hook_ops *reg)
{
     struct nf_hook_ops *elem;
     int err;

     err = mutex_lock_interruptible(&nf_hook_mutex);
     if (err < 0)
          return err;

在对应的钩子点如nf_hooks[ipv4][FORWARD]列出所有已经注册了的钩子函数,根据优先级找到合适的插入点
     list_for_each_entry(elem, &nf_hooks[reg->pf][reg->hooknum], list) {
          if (reg->priority < elem->priority)
               break;
     }

将nf_hook_ops结构中的list_head节点插入到该链表中
     list_add_rcu(®->list, elem->list.prev);
     mutex_unlock(&nf_hook_mutex);
#if defined(CONFIG_JUMP_LABEL)
     static_key_slow_inc(&nf_hooks_needed[reg->pf][reg->hooknum]);
#endif
     return 0;
}
阅读(2286) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~