2024年3月28日发(作者:)
一.连接记录的存储
相关函数:
static inline struct nf_conn *nf_ct_tuplehash_to_ctrack(const struct
nf_conntrack_tuple_hash *hash)
static inline struct nf_conn *nf_ct_get(const struct sk_buff *skb, enum ip_conntrack_info
*ctinfo)
nf_conntrack中tuple存储如上图所示。在struct nf_conntrack_tuple_hash中,成员hnode链接入
ct->hash[]->first中的。实际的记录在保存在struct nf_conntrack_tuple中。
1.记录的访问:
hlist_nulls_for_each_entry_rcu
103 #define hlist_nulls_for_each_entry_rcu(tpos, pos, head, member)
104 for (pos = rcu_dereference((head)->first);
105 (!is_a_nulls(pos)) &&
106 ({ tpos = hlist_nulls_entry(pos, typeof(*tpos), member); 1; });
107 pos = rcu_dereference(pos->next))
108
参见 /net/netfilter/nf_conntrack_core.c __nf_conntrack_find函数;
struct nf_conntrack_tuple_hash *h;
struct hlist_nulls_node *n;
hlist_nulls_for_each_entry_rcu(h, n, &net->[hash], hnnode)
2.记录的添加
84 static inline void hlist_nulls_add_head_rcu(struct hlist_nulls_node *n,
85 struct hlist_nulls_head *h)
86 {
87 struct hlist_nulls_node *first = h->first;
88
89 n->next = first;
90 n->pprev = &h->first;
91 rcu_assign_pointer(h->first, n);
92 if (!is_a_nulls(first))
93 first->pprev = &n->next;
94 }
参见/net/netfilter/nf_conntrack_core.c:
313 static void __nf_conntrack_hash_insert(struct nf_conn *ct,
314 unsigned int hash,
315 unsigned int repl_hash)
316 {
317 struct net *net = nf_ct_net(ct);
318
319 hlist_nulls_add_head_rcu(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnnode,
320 &net->[hash]);
321 hlist_nulls_add_head_rcu(&ct->tuplehash[IP_CT_DIR_REPLY].hnnode,
322 &net->[repl_hash]);
323 }
3.记录的删除
59 static inline void hlist_nulls_del_rcu(struct hlist_nulls_node *n)
60 {
61 __hlist_nulls_del(n);
62 n->pprev = LIST_POISON2;
63 }
59 static inline void __hlist_nulls_del(struct hlist_nulls_node *n)
60 {
61 struct hlist_nulls_node *next = n->next;


发布评论