连接跟踪(connection tracking,conntrack,CT),连接跟踪是许多网络应用的基础。例如,Kubernetes Service、 四层 LVS/IPVS、Docker network、OVS、iptables 主机防火墙等等。可以理解跟踪(并记录)连接的状态。
- 从数据包中提取信息,数据流(flow)和对应的连接(conn)
- 为连接维护一个状态表(conntrack table),例如连接的创建时间、发送包数、发送字节数等
- 回收过期连接
- 为更上层(例如 NAT)提供服务
    结构体 nf_conntrack_tuple
   
一个 nf_conntrack_tuple 定义一个单向 flow,整体看,分为 src 和 dst,源和目的信息。其定义在文件 include/net/netfilter/nf_conntrack_tuple.h,对于结构体 nf_conntrack_man_proto 定义支持协议包括,TCP UDP ICMP DCCP SCTP GRE
/* This contains the information to distinguish a connection. */
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;
		......
		/* The protocol. */
		u_int8_t protonum;
		/* The direction (for tuplehash) */
		u_int8_t dir;
	} dst;
};
    结构体 nf_conn
   
Netfilter 中每个 flow 都称为一个 connection, tuplehash 为连接跟踪 nf_conntrack_tuple 的 hash,分入和出两个方向
struct nf_conn {
	/* Usage count in here is 1 for hash table/destruct timer, 1 per skb,
           plus 1 for any connection(s) we are `master' for */
	struct nf_conntrack ct_general;
	spinlock_t lock;
	/* XXX should I move this to the tail ? - Y.K */
	/* These are my tuples; original and reply */
	struct nf_conntrack_tuple_hash tuplehash[IP_CT_DIR_MAX];
	/* Have we seen traffic both ways yet? (bitset) */
	unsigned long status;
	/* If we were expected by an expectation, this will be it */
	struct nf_conn *master;
	/* Timer function; drops refcnt when it goes off. */
	struct timer_list timeout;
#if defined(CONFIG_NF_CONNTRACK_MARK)
	u_int32_t mark;
#endif
#ifdef CONFIG_NF_CONNTRACK_SECMARK
	u_int32_t secmark;
#endif
	/* Storage reserved for other modules: */
	union nf_conntrack_proto proto;
	/* Extensions */
	struct nf_ct_ext *ext;
#ifdef CONFIG_NET_NS
	struct net *ct_net;
#endif
};
    入口模块加载
   
定义文件 net/netfilter/nf_conntrack_standalone.c
module_init(nf_conntrack_standalone_init);
module_exit(nf_conntrack_standalone_fini);
     
   
    1.  初始化函数 nf_conntrack_net_init
   
    2.  函数 ipv4_conntrack_in
   
ipv4_conntrack_in 主要完成的工作就是判断数据包是否已在连接跟踪表中,如果不在,则为数据包实例化并初始化 ip_conntrack,为这个数据包设置连接状态。
如果之前已经有记录跟踪则直接 ACCEPT
unsigned int
nf_conntrack_in(struct net *net, u_int8_t pf, unsigned int hooknum,
		struct sk_buff *skb)
    2.1 resolve_normal_ct 核心函数
   
 
版权声明:本文为zhonglinzhang原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
