看看 NF_HOOK 宏

IPVS软件结构与实现

 LVS 软件的核心是运行在LB上的IPVS,它使用基于IP层的负载均衡方法。IPVS的总体结构主要由IP包处理、负载均衡算法、 系统配置与 管理三个模块及虚拟 服务器与真实 服务器链表组成。

  2.1 LVS对 IP包的处理模式

  IP包处理用Linux 2.4 内核的Netfilter框架完成。一个数据包通过Netfilter框架的过程如图所示:

  通俗的说,netfilter的架构就是在整个 网络流程的若干位置放置了一些检测点(HOOK),而在每个检测点上上登记了一些处理函数进行处理(如包过滤,NAT等,甚至可以是用户自定义的功能)。

NF_IP_PRE_ROUTING:刚刚进入网络层的数据包通过此点(刚刚进行完版本号,校验和等检测),源地址转换在此点进行;
NF_IP_LOCAL_IN:经路由查找后,送往本机的通过此检查点,INPUT包过滤在此点进行;
NF_IP_FORWARD:要转发的包通过此检测点,FORWORD包过滤在此点进行;
NF_IP_LOCAL_OUT:本机进程发出的包通过此检测点,OUTPUT包过滤在此点进行;
NF_IP_POST_ROUTING:所有马上便要通过网络设备出去的包通过此检测点,内置的目的地址转换功能(包括地址伪装)在此点进行。

  在IP层代码中,有一些带有NF_HOOK宏的语句,如IP的转发函数中有:

NF_HOOK(PF_INET, NF_IP_FORWARD, skb, skb->dev, dev2,ip_forward_finish);
//其中NF_HOOK宏的定义基本如下:

#ifdef CONFIG_NETFILTER
#define NF_HOOK(pf, hook, skb, indev, outdev, okfn)
(list_empty(&nf_hooks[(pf)][(hook)])
? (okfn)(skb)
: nf_hook_slow((pf), (hook), (skb), (indev), (outdev), (okfn)))
#else /* !CONFIG_NETFILTER */
#define NF_HOOK(pf, hook, skb, indev, outdev, okfn) (okfn)(skb)
#endif /*CONFIG_NETFILTER*/

  如果在编译内核时没有配置netfilter时,就相当于调用最后一个参数,此例中即执行ip_forward_finish函数;否则进入HOOK 点,执行通过nf_register_hook()登记的功能(这句话表达的可能比较含糊,实际是进入nf_hook_slow()函数,再由它执行登记 的函数)。

  NF_HOOK宏的参数分别为:

pf:协议族名,netfilter架构同样可以用于IP层之外,因此这个变量还可以有诸如PF_INET6,PF_DECnet等名字。
hook:HOOK点的名字,对于IP层,就是取上面的五个值;
skb:顾名思义
indev:进来的设备,以struct net_device结构表示;
outdev:出去的设备,以struct net_device结构表示;
okfn:是个函数指针,当所有的该HOOK点的所有登记函数调用完后,转而走此流程。

  这些点是已经在内核中定义好的,除非你是这部分内核代码的 维护者,否则无权增加或修改,而在此检测点进行的处理,则可由用户指定。像packet filter,NAT,connection track这些功能,也是以这种方式提供的。正如netfilter的当初的设计目标--提供一个完善灵活的框架,为扩展功能提供方便。

  如果我们想加入自己的代码,便要用nf_register_hook函数,其函数原型为:

int nf_register_hook(struct nf_hook_ops *reg)
struct nf_hook_ops://结构
struct nf_hook_ops
{
struct list_head list;
/* User fills in from here down. */
nf_hookfn *hook;
int pf;
int hooknum;
/* Hooks are ordered in ascending priority. */
int priority;
};

  其实,类似LVS的做法就是生成一个struct nf_hook_ops结构的实例,并用nf_register_hook将其HOOK上。其中list项要初始化为{NULL,NULL};由于一般在 IP层工作,pf总是PF_INET;hooknum就是HOOK点;一个HOOK点可能挂多个处理函数,谁先谁后,便要看优先级,即priority的 指定了。netfilter_ipv4.h中用一个枚举类型指定了内置的处理函数的优先级:

enum nf_ip_hook_priorities {
NF_IP_PRI_FIRST = INT_MIN,
NF_IP_PRI_CONNTRACK = -200,
NF_IP_PRI_MANGLE = -150,
NF_IP_PRI_NAT_DST = -100,
NF_IP_PRI_FILTER = 0,
NF_IP_PRI_NAT_SRC = 100,
NF_IP_PRI_LAST = INT_MAX,
};

  hook是提供的处理函数,也就是我们的主要工作,其原型为:

unsigned int nf_hookfn(unsigned int hooknum,
struct sk_buff **skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *));

  它的五个参数将由NFHOOK宏传进去。

  以上是NetFillter编写自己模块时的一些基本用法,接下来,我们来看一下LVS中是如何实现的。

 

    其他文章: http://www.haoxiai.net/wangluojichu/fanghuoqiang/72946.html

转载于:https://www.cnblogs.com/jinrize/archive/2009/11/09/1599067.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值