ip conntrack 基本原理与实现

  • Post author:
  • Post category:其他


连接跟踪(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 版权协议,转载请附上原文出处链接和本声明。