linux下的Netfilter&iptables:filtile表中如何向链中挂载处理函数

 

挂载钩子处理函数都是在初始化中做的  filtile表则是在iptable_filter_init函数中将iptable_filter_hook函数注册到NF_BR_LOCAL_IN NF_BR_FORWARD NF_BR_LOCAL_OUT 链上。

函数调用关系如下  内核Linux 4.14版本

static int __init iptable_filter_init(void)
{
    int ret;

    ret = register_pernet_subsys(&iptable_filter_net_ops);
    if (ret < 0)
        return ret;

    /* Register hooks */
    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);
    }

    return ret;
}
 

static const struct xt_table packet_filter = {
    .name        = "filter",
    .valid_hooks    = FILTER_VALID_HOOKS,
    .me        = THIS_MODULE,
    .af        = NFPROTO_ARP,
    .priority    = NF_IP_PRI_FILTER,
};

 #define FILTER_VALID_HOOKS ((1 << NF_BR_LOCAL_IN) | (1 << NF_BR_FORWARD) | \
   (1 << NF_BR_LOCAL_OUT))

/****注册钩子处理函数  把处理函数放到钩子上*****/

/**
 * xt_hook_link - set up hooks for a new table
 * @table:    table with metadata needed to set up hooks
 * @fn:        Hook function
 *
 * This function will take care of creating and registering the necessary
 * Netfilter hooks for XT tables.
 */
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);

/**********for循环把处理函数放到钩子上************/

    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;
}
EXPORT_SYMBOL_GPL(xt_hook_link);

 

int nf_register_hooks(struct nf_hook_ops *reg, unsigned int n)
{
    unsigned int i;
    int err = 0;

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

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

 

int nf_register_hook(struct nf_hook_ops *reg)
{
    struct nf_hook_ops *elem;

    mutex_lock(&nf_hook_mutex);

/**********nf_hooks为全局变量  是个二维数组***************/
    list_for_each_entry(elem, &nf_hooks[reg->pf][reg->hooknum], list) {
        if (reg->priority < elem->priority)
            break;
    }
    list_add_rcu(&reg->list, elem->list.prev);
    mutex_unlock(&nf_hook_mutex);
#ifdef HAVE_JUMP_LABEL
    static_key_slow_inc(&nf_hooks_needed[reg->pf][reg->hooknum]);
#endif
    return 0;
}
EXPORT_SYMBOL(nf_register_hook);

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值