Netfilter 之 连接跟踪相关数据结构
Netfilter通过连接跟踪来记录和跟踪连接的状态,为状态防火墙和NAT提供基础支持;
钩子点与钩子函数
下图为钩子点和钩子函数的关系图(点击图片查看原图),其中ipv4_conntrack_defrag、ipv4_conntrack_in、ipv4_helper、ipv4_confirm为连接跟踪相关的钩子函数,其作用的钩子点为PRE_ROUTING、LOCAL_IN、LOCAL_OUT、POST_ROUTING:

钩子函数的调用流程
通过上图,可以得到连接跟踪的流程:
输入本地:
ipv4_conntrack_defrag–>ipv4_conntrack_in–>ipv4_helper–>ipv4_confirm
【<————-PRE_ROUTING————>】 【<—— LOCAL_IN——>】
转发:
ipv4_conntrack_defrag–>ipv4_conntrack_in–>ipv4_helper–>ipv4_confirm
【<————-PRE_ROUTING————>】 【<—— LOCAL_IN——>】
本地输出:
ipv4_conntrack_defrag–>ipv4_conntrack_local–>ipv4_helper–>ipv4_confirm
【<————–LOCAL_OUT—————–>】 【<—-POST_ROUTING—>】
连接跟踪的状态
ip_conntrack_info用来描述连接跟踪的状态,如下:
enum ip_conntrack_info {
/* Part of an established connection (either direction). */
/* 已建立连接的一部分(任一方向) */
IP_CT_ESTABLISHED,
/* Like NEW, but related to an existing connection, or ICMP error
(in either direction). */
/* 已建立连接的关联连接,或者是ICMP错误(任一方向) */
IP_CT_RELATED,
/* Started a new connection to track (only
IP_CT_DIR_ORIGINAL); may be a retransmission. */
/* 开始一个新连接; 可能是重传 */
IP_CT_NEW,
/* >= this indicates reply direction */
/* >=这个值的都是响应方向的 */
IP_CT_IS_REPLY,
/* 已建立连接的响应 */
IP_CT_ESTABLISHED_REPLY = IP_CT_ESTABLISHED + IP_CT_IS_REPLY,
/* 已建立连接的关联连接的响应 */
IP_CT_RELATED_REPLY = IP_CT_RELATED + IP_CT_IS_REPLY,
/* No NEW in reply direction. */
/* Number of distinct IP_CT types. */
/* IP_CT类型的数量 */
IP_CT_NUMBER,
/* only for userspace compatibility */
#ifndef __KERNEL__
IP_CT_NEW_REPLY = IP_CT_NUMBER,
#else
IP_CT_UNTRACKED = ,
#endif
};
数据结构图
本文中涉及的数据结构之间的关系图如下:

源码分析
nf_conn是对连接跟踪抽象的基础结构,其中tuplehash为连接跟踪nf_conntrack_tuple的hash,分两个方向;
struct nf_conn {
/* Usage count in here is 1 for hash table, 1 per skb,
* plus 1 for any connection(s) we are `master' for
*
* Hint, SKB address this struct and refcnt via skb->_nfct and
* helpers nf_conntrack_get() and nf_conntrack_put().
* Helper nf_ct_put() equals nf_conntrack_put() by dec refcnt,
* beware nf_ct_get() is different and don't inc refcnt.
*/
/* 连接跟踪的引用计数 */
struct nf_conntrack ct_general;
spinlock_t lock;
u16 cpu;
#ifdef CONFIG_NF_CONNTRACK_ZONES
struct nf_conntrack_zone zone;
#endif
/* XXX should I move this to the tail ? - Y.K */
/* These are my tuples; original and reply */
/* 连接跟踪两个方向的tuple节点,即五元组 */
struct nf_conntrack_tuple_hash tuplehash[IP_CT_DIR_MAX];
/* Have we seen traffic both ways yet? (bitset) */
/* 状态 */
unsigned long status;
/* jiffies32 when this ct is considered dead */
/* 连接跟踪的超时时间 */
u32 timeout;
/* 命名空间 */
possible_net_t ct_net;
#if IS_ENABLED(CONFIG_NF_NAT)
struct rhlist_head nat_bysource;
#endif
/* all members below initialized via memset */
u8 __nfct_init_offset[];
/* If we were expected by an expectation, this will be it */
/* 如果当前连接是某个连接期望的连接,该字段指向主连接 */
struct nf_conn *master;
#if defined(CONFIG_NF_CONNTRACK_MARK)
u_int32_t mark;
#endif
#ifdef CONFIG_NF_CONNTRACK_SECMARK
u_int32_t secmark;
#endif
/* Extensions */
/* 扩展项 */
struct nf_ct_ext *ext;
/* Storage reserved for other modules, must be the last member */
/* 不同协议实现连接跟踪的额外参数 */
union nf_conntrack_proto proto;
};
nf_conntrack_tuple_hash的定义如下:
struct nf_conntrack_tuple_hash {
struct hlist_nulls_node hnnode;
struct nf_conntrack_tuple tuple;
};
nf_ct_ext用于实现对连接跟踪的扩展;
struct nf_ct_ext {
struct rcu_head rcu;
u8 offset[NF_CT_EXT_NUM];
u8 len;
char data[];
};
nf_conntrack_tuple是用来区分一条连接的信息,定义如下:
/* 该结构包含源目的信息用来区分一条连接 */
struct nf_conntrack_tuple {
/* 源,可操作? */
struct nf_conntrack_man src; /* These are the parts of the tuple which are fixed. */
/* 目的,不可操作? */
struct {
union nf_inet_addr u3;
union {
/* Add other protocols here. */
__be16 all; struct {
__be16 port;
} tcp;
struct {
__be16 port;
} udp;
struct {
u_int8_t type, code;
} icmp;
struct {
__be16 port;
} dccp;
struct {
__be16 port;
} sctp;
struct {
__be16 key;
} gre;
} u; /* The protocol. */
/* 协议 */
u_int8_t protonum; /* The direction (for tuplehash) */
/* 方向(tuplehash使用) */
u_int8_t dir;
} dst;
};
上面结构中的源方向信息使用了nf_conntrack_man结构,其中包括了三层识别信息,四层识别信息,以及三层协议号;
/* The manipulable part of the tuple. */
/* tuple可操作的部分? */
struct nf_conntrack_man {
/* 三层识别信息 */
union nf_inet_addr u3;
/* 四层识别信息 */
union nf_conntrack_man_proto u;
/* Layer 3 protocol */
/* 三层协议号 */
u_int16_t l3num;
};
union nf_inet_addr {
__u32 all[];
__be32 ip;
__be32 ip6[];
struct in_addr in;
struct in6_addr in6;
};
/* The protocol-specific manipulable parts of the tuple: always in
* network order
*/
union nf_conntrack_man_proto {
/* Add other protocols here. */
__be16 all; struct {
__be16 port;
} tcp;
struct {
__be16 port;
} udp;
struct {
__be16 id;
} icmp;
struct {
__be16 port;
} dccp;
struct {
__be16 port;
} sctp;
struct {
__be16 key; /* GRE key is 32bit, PPtP only uses 16bit */
} gre;
};
nf_conn中的proto成员用来存储协议特有的用来表示连接跟踪的信息,其联合体nf_conntack_proto定义如下:
/* per conntrack: protocol private data */
union nf_conntrack_proto {
/* insert conntrack proto private data here */
struct nf_ct_dccp dccp;
struct ip_ct_sctp sctp;
struct ip_ct_tcp tcp;
struct nf_ct_gre gre;
unsigned int tmpl_padto;
};
下面是TCP的一些必要信息;
struct ip_ct_tcp {
struct ip_ct_tcp_state seen[]; /* connection parameters per direction */
u_int8_t state; /* state of the connection (enum tcp_conntrack) */
/* For detecting stale connections */
u_int8_t last_dir; /* Direction of the last packet (enum ip_conntrack_dir) */
u_int8_t retrans; /* Number of retransmitted packets */
u_int8_t last_index; /* Index of the last packet */
u_int32_t last_seq; /* Last sequence number seen in dir */
u_int32_t last_ack; /* Last sequence number seen in opposite dir */
u_int32_t last_end; /* Last seq + len */
u_int16_t last_win; /* Last window advertisement seen in dir */
/* For SYN packets while we may be out-of-sync */
u_int8_t last_wscale; /* Last window scaling factor seen */
u_int8_t last_flags; /* Last flags set */
};
struct ip_ct_tcp_state {
u_int32_t td_end; /* max of seq + len */
u_int32_t td_maxend; /* max of ack + max(win, 1) */
u_int32_t td_maxwin; /* max(win) */
u_int32_t td_maxack; /* max of ack */
u_int8_t td_scale; /* window scale factor */
u_int8_t flags; /* per direction options */
};
Netfilter 之 连接跟踪相关数据结构的更多相关文章
- Netfilter之连接跟踪实现机制初步分析
Netfilter之连接跟踪实现机制初步分析 原文: http://blog.chinaunix.net/uid-22227409-id-2656910.html 什么是连接跟踪 连接跟踪(CONNT ...
- Netfilter 之 连接跟踪钩子函数分析
ipv4_conntrack_defrag ipv4_conntrack_defrag对输入包进行检查,如果是分片包,则调用nf_ct_ipv4_gather_frags函数进行重组: static ...
- Netfilter 之 连接跟踪初始化
基础参数初始化 nf_conntrack_init_start函数完成连接跟踪基础参数的初始化,包括了hash,slab,扩展项,GC任务等: int nf_conntrack_init_start( ...
- Netfilter 之 连接跟踪的helper
注册helper nf_conntrack_ftp_init是连接跟踪ftp模块的初始化函数,可以看到其调用了nf_conntrack_helpers_register来注册helper: stati ...
- Netfilter&iptables:如何理解连接跟踪机制?
如何理解Netfilter中的连接跟踪机制? 本篇我打算以一个问句开头,因为在知识探索的道路上只有多问然后充分调动起思考的机器才能让自己走得更远.连接跟踪定义很简单:用来记录和跟踪连接的状态. 问:为 ...
- linux内核netfilter连接跟踪的hash算法
linux内核netfilter连接跟踪的hash算法 linux内核中的netfilter是一款强大的基于状态的防火墙,具有连接跟踪(conntrack)的实现.conntrack是netfilte ...
- linux nf_conntrack 连接跟踪机制
PRE_ROUTING和LOCAL_OUT点可以看作是整个netfilter的入口,而POST_ROUTING和LOCAL_IN可以看作是其出口; 报文到本地:PRE_ROUTING----LOCAL ...
- [转]nf_conntrack: table full, dropping packet 连接跟踪表已满,开始丢包 的解决办法
nf_conntrack: table full, dropping packet 连接跟踪表已满,开始丢包 的解决办法 中午业务说机器不能登录,我通过USM管理界面登录单板的时候发现机器没有僵 ...
- linux nf_conntrack 连接跟踪机制 3-hook
conntrack hook函数分析 enum nf_ip_hook_priorities { NF_IP_PRI_FIRST = INT_MIN, NF_IP_PRI_CONNTRACK_DEFRA ...
随机推荐
- Spark机器学习API之特征处理(二)
Spark机器学习库中包含了两种实现方式,一种是spark.mllib,这种是基础的API,基于RDDs之上构建,另一种是spark.ml,这种是higher-level API,基于DataFram ...
- vue关于路由容易忽略的点
1.去掉导航里的# 在router.js中 export default new Router{ mode:'history' } 2.指定激活项的class 在router.js中 export d ...
- 5.安装bacula-web(监控页面)
1. 安装bacula-web(监控页面) 用途:监控bacula状态. http://docs.bacula-web.org/en/master/index.html bacula-web-7. ...
- 07_Hive的基本命令_Insert命令
1.将查询结果插入Hive表语法结构: 1.1.基本模式插入: INSERT OVERWRITE TABLE tablename1 [PARTITION (partcol1=val1, partcol ...
- zabbix上添加交换机监控记事
zabbix上添加交换机监控记事 第一次使用zabbix来添加监控华为s5720交换机,根本找不到头绪,像个无头的苍蝇一样的百度来处理,结果都没有任何效果,给自己增加了很多痛苦和心烦,增加不少 ...
- Pc贪吃蛇
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- 一图一知-TS之函数function
- ACM-ICPC 2018 南京赛区网络预赛 K. The Great Nim Game(博弈)
题目链接:https://nanti.jisuanke.com/t/31000 题意:有N堆石子(N为大数),每堆的个数按一定方式生成,问先手取若干堆进行尼姆博弈,必胜的方式有多少种. 题解:因为 k ...
- 如何复制word的图文到ueditor中自动上传?
官网地址http://ueditor.baidu.com Git 地址 https://github.com/fex-team/ueditor 参考博客地址 http://blog.ncmem.com ...
- (十七)线程,connect的第五个参数
采用多线程,将需要处理的后台数据放入子线程,为了能够跨线程调用,一种方法是使用类似线程锁对线程进行保护,另外一种方法使用Qt的信号槽机制.Qt的信号槽机制采用connect函数进行连接,connect ...