您的位置:首页 > 运维架构 > 网站架构

linux2.6内核netfilter架构分析

2015-07-01 06:28 567 查看
1.2.6内核的netfilter与2.4的有很大不同:

ChangeLog-2.6.15中有下面这样的描述:
commit9fb9cbb1082d6b31fb45aa1a14432449a0df6cf1
Author:YasuyukiKozakai<yasuyuki.kozakai@toshiba.co.jp>
Date:WedNov916:38:162005-0800

[NETFILTER]:Addnf_conntracksubsystem.

Theexistingconnectiontrackingsubsysteminnetfiltercanonly
handleipv4.Therewerebasicallytwochoicespresenttoadd
connectiontrackingsupportforipv6.Wecouldeitherduplicateall
oftheipv4connectiontrackingcodeintoanipv6counterpart,or(the
choicetakenbythesepatches)wecoulddesignagenericlayerthat
couldhandlebothipv4andipv6andthusrequiringonlyonesub-protocol
(TCP,UDP,etc.)connectiontrackinghelpermoduletobewritten.

Infactnf_conntrackiscapableofworkingwithanylayer3
protocol.
即2.6中的netfilter将支持任何3层协议,而原来的ip_conntrack将是它的一个子集。
2.2.6中netfilter目录结构分析

net\netfilter目录:新增netfilter

net\ipv4\netfilter目录:ipv4的netfilter

net\ipv6\netfilter目录:ipv6的netfilter

2.2.6内核netfilter提供的功能

²支持netfilter的sockopt:只有getsockopt操作;通过nf_register_sockopt进行注册;

²

以下以ipv4进行分析

3.ConntrackHook函数的注册位置:nf_conntrack_l3proto_ipv4.c文件

NatHook函数的注册位置:nf_nat_standalone.c文件



4.进入PREROUTING,


入口函数ipv4_conntrack_in(ipv4_conntrack_defrag只是重组报文,非此处重点,故忽略之)直接调用nf_conntrack_in(PF_INET,hooknum,pskb):

²调用l3proto=__nf_ct_l3proto_find((u_int16_t)pf);,得到3层协议指针:nf_conntrack_l3proto_ipv4;

²调用l3proto->prepare(ipv4_prepare),得到skb的4层协议和数据字段偏移量;

²调用l4proto=__nf_ct_l4proto_find((u_int16_t)pf,protonum);,得到4层协议指针:

nf_conntrack_l4proto_tcp4或nf_conntrack_l4proto_udp4,……

以下以nf_conntrack_l4proto_tcp4为分析对象

²调用l4proto->error,对报文进行校验;校验通过,则:

²调用resolve_normal_ct(nf_conntrack_core.c)对报文进行进一步处理:

Ø调用nf_ct_get_tuple,得到skb对应的tuple;

Ø调用nf_conntrack_find_get,查找tuple对应的conntrackhash是否存在;若不存在,则调用init_conntrack(nf_conntrack_core.c)进行tuple对应的conntrack的初始化:

ü调用nf_ct_invert_tuple,得到反向tuple:repl_tuple;

ü调用__nf_conntrack_expect_find,查找所属exp;

ü调用__nf_conntrack_alloc,分配conntrack结构内存,并初始化;

ü调用find_expectation,再次查找exp(why?)

n若找到,则进行控制报文和数据报文的关联;

n若没有,则调用__nf_ct_helper_find查找helper;

Ø调用nf_ct_tuplehash_to_ctrack,由hash得到对应的conntrack;

Ø根据hash的属性,更改conntrack的状态值。

²调用l4proto->packet,对报文的4层协议进行处理;

入口函数nf_nat_in,调用nf_nat_fn:

²调用nf_ct_get,得到skb对应的nf_conn:ct

²调用nfct_nat,得到ct的nf_conn_nat:nat;

²根据ctinfo值,做不同处理:

Øctinfo为IP_CT_NEW,则根据nat规则(有可能是空规则),建立nf_nat_range;并根据nf_nat_range更改conntrack信息;

Øctinfo为IP_CT_RELATED或IP_CT_RELATED+IP_CT_IS_REPLY,且报文不是ICMP,则进入IP_CT_NEW的处理内容进行处理;

²调用nf_nat_packet,根据转换的conntrack,更改报文的地址信息;

5.进入LOCAL_IN,则



入口函数:nf_nat_fn:

入口函数:ipv4_conntrack_help:

²得到conntrack的help,调用helper的handle处理之;

入口函数:nf_nat_adjust:

²调整TCP报文的序列号,以及conntrack上的TCP记录信息(只对TCP报文有效)

入口函数:ipv4_confirm:

²调用ipv4_confirm,直接调用nf_conntrack_confirm,再调用__nf_conntrack_confirm:

Ø将conntrack加入链表

6.进入LOCAL_OUT,则



入口函数:ipv4_conntrack_defrag,进行报文碎片重组;

入口函数:ipv4_conntrack_local,调用nf_conntrack_in处理之;后续同第4节描述

入口函数:nf_nat_local_fn,

²调用nf_nat_fn,

²调用ip_route_me_harder

7.进入POSTROUTING,则:



入口函数:nf_nat_out,

²调用nf_nat_fn;

²调用ip_xfrm_me_harder(定义CONFIG_XFRM的情况下)

入口函数:ipv4_conntrack_help:

²得到conntrack的help,调用helper的handle处理之;

入口函数:nf_nat_adjust:

入口函数:ipv4_confirm,直接调用nf_conntrack_confirm,再调用__nf_conntrack_confirm:

²将conntrack加入链表
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: