加入收藏 | 设为首页 | 会员中心 | 我要投稿 云计算网_宿迁站长网 (https://www.0527zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 服务器 > 搭建环境 > Linux > 正文

Linux内核分析 - 网络[七]:NetFilter

发布时间:2016-01-26 04:16:56 所属栏目:Linux 来源:网络整理
导读:内核版本:2.6.34 NetFilter在2.4.x内核中引入,成为linux平台下进行网络应用的主要扩展,不仅包括防火墙的实现 ,还包括报文的处理(如报文加密、报文分类统计等
副标题[/!--empirenews.page--]

内核版本:2.6.34

NetFilter在2.4.x内核中引入,成为linux平台下进行网络应用的主要扩展,不仅包括防火墙的实现 ,还包括报文的处理(如报文加密、报文分类统计等)等。

NetFilter数据结构        勾子struct nf_hook_ops[netfiltercore.c]

struct nf_hook_ops {     
    struct list_head list;     
    /* User fills in from here down. */ 
    nf_hookfn *hook;     
    struct module *owner;     
    u_int8_t pf;     
    unsigned int hooknum;     
    /* Hooks are ordered in ascending priority. */ 
    int priority;     
};

成员list用于链入全局勾子数组nf_hooks中,它一定在第一位,保证&nf_hook_ops->list的值与 &nf_hook_ops相同,稍后在使用时会用到这一技巧;

成员hook即用户定义的勾子函数;owner表示注册这个勾子函数的模 块,因为netfilter是内核空间的,所以一般为模块来完成勾子函数注册;pf与hooknum一起索引到特定协议特定编号的勾子函数 队列,用于索引nf_hooks;priority决定在同一队列(pf与hooknum相同)的顺序,priority越小则排列越靠前。

struct nf_hook_ops只是存储勾子的数据结构,而真正存储这些勾子供协议栈调用的是nf_hooks,从定义可以看出,它其实就是二维数 组的链表。

struct list_head nf_hooks[NFPROTO_NUMPROTO][NF_MAX_HOOKS]; [netfiltercore.c]

其中NFPROTO_NUMPROTO表示勾子关联的协议,可取值:

enum {     
    NFPROTO_UNSPEC =  0,     
    NFPROTO_IPV4   =  2,     
    NFPROTO_ARP    =  3,     
    NFPROTO_BRIDGE =  7,     
    NFPROTO_IPV6   = 10,     
    NFPROTO_DECNET = 12,     
    NFPROTO_NUMPROTO,     
};

NF_MAX_HOOKS表示勾子应用的位置,可选值在每个协议模块内部定义,这些值代表了勾子函数在协议流程中应用的 位置(稍后会以bridge为例详细说明),大致上都有以下值:

NF_XXX_PRE_ROUTING,     
NF_XXX_LOCAL_IN,     
NF_XXX_FORWARD,     
NF_XXX_LOCAL_OUT,     
NF_XXX_POST_ROUTING,     
NF_XXX_NUMHOOKS

NetFilter注册

在了解了nf_hook_ops和nf_hooks后,来看下如何操作nf_hooks中的元素。

nf_register_hook()将nf_hook_ops注册到nf_hooks中:

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;     
    list_for_each_entry(elem, &nf_hooks[reg->pf][reg->hooknum], list) {     
        if (reg->priority < elem->priority)     
            break;     
    }     
    list_add_rcu(?->list, elem->list.prev);     
    mutex_unlock(&nf_hook_mutex);     
    return 0;     
}

这个函数很简单,从指定pf&hooknum的nf_hooks队列遍历,按priority从小到大顺序,将reg插入相应位置,完 成勾子函数的注册。

nf_unregister_hook()将nf_hook_ops从nf_hooks中注销掉:

void nf_unregister_hook

(struct nf_hook_ops *reg)     
{     
    mutex_lock(&nf_hook_mutex);     
    list_del_rcu(?->list);     
    mutex_unlock(&nf_hook_mutex);     
    synchronize_net();     
}

这个函数更简单,从nf_hooks中删除reg。

内核同时还提供了nf_register_hooks()和nf_unregister_hooks(),将reg重复注册n次或将reg从nf_hooks中注销n次。当勾子函数注册完成后,nf_hooks的结构如图所示:

Linux内核分析 - 网络[七]:NetFilter

(编辑:云计算网_宿迁站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!