- 论坛徽章:
- 1
|
回复 2# asuka2001
非常感谢,我跟踪出的结果也是ct为空,但是我又有一些疑问
①当在访问哈希表之前,加了spin_lock_bh(&nf_conntrack_lock)锁之后,在没解锁之前,哈希表中的连接会因为超时被释放吗?
ctnetlink_dump_table代码如下:
- static int
- ctnetlink_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
- {
- struct net *net = sock_net(skb->sk);
- struct nf_conn *ct, *last;
- struct nf_conntrack_tuple_hash *h;
- struct hlist_nulls_node *n;
- struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh);
- u_int8_t l3proto = nfmsg->nfgen_family;
- spin_lock_bh(&nf_conntrack_lock);
- last = (struct nf_conn *)cb->args[1];
- for (; cb->args[0] < net->ct.htable_size; cb->args[0]++) {
- restart:
- hlist_nulls_for_each_entry(h, n, &net->ct.hash[cb->args[0]],
- hnnode) {
- if (NF_CT_DIRECTION(h) != IP_CT_DIR_ORIGINAL)
- continue;
- ct = nf_ct_tuplehash_to_ctrack(h);
- /* Dump entries of a given L3 protocol number.
- * If it is not specified, ie. l3proto == 0,
- * then dump everything. */
- if (l3proto && nf_ct_l3num(ct) != l3proto)
- continue;
- if (cb->args[1]) {
- if (ct != last)
- continue;
- cb->args[1] = 0;
- }
- if (ctnetlink_fill_info(skb, NETLINK_CB(cb->skb).pid,
- cb->nlh->nlmsg_seq,
- IPCTNL_MSG_CT_NEW, ct) < 0) {
- nf_conntrack_get(&ct->ct_general);
- cb->args[1] = (unsigned long)ct;
- goto out;
- }
- if (NFNL_MSG_TYPE(cb->nlh->nlmsg_type) ==
- IPCTNL_MSG_CT_GET_CTRZERO) {
- struct nf_conn_counter *acct;
- acct = nf_conn_acct_find(ct);
- if (acct)
- memset(acct, 0, sizeof(struct nf_conn_counter[IP_CT_DIR_MAX]));
- }
- }
- if (cb->args[1]) {
- cb->args[1] = 0;
- goto restart;
- }
- }
- out:
- spin_unlock_bh(&nf_conntrack_lock);
- if (last)
- nf_ct_put(last);
- return skb->len;
- }
复制代码 ②假设传入的ct是空指针的话,在ctnetlink_fill_info()函数中,在进入ctnetlink_dump_tuples()函数之前,有一次访问ct内容的操作,
nfmsg->nfgen_family = nf_ct_l3num(ct),如果ct是NULL的话,在这里不就应该报错了吗?- static int
- ctnetlink_fill_info(struct sk_buff *skb, u32 pid, u32 seq,
- int event, struct nf_conn *ct)
- {
- struct nlmsghdr *nlh;
- struct nfgenmsg *nfmsg;
- struct nlattr *nest_parms;
- unsigned int flags = pid ? NLM_F_MULTI : 0;
- event |= NFNL_SUBSYS_CTNETLINK << 8;
- nlh = nlmsg_put(skb, pid, seq, event, sizeof(*nfmsg), flags);
- if (nlh == NULL)
- goto nlmsg_failure;
- nfmsg = nlmsg_data(nlh);
- nfmsg->nfgen_family = nf_ct_l3num(ct);
- nfmsg->version = NFNETLINK_V0;
- nfmsg->res_id = 0;
- ......
- }
复制代码 nf_ct_l3num()函数代码:- static inline u_int16_t nf_ct_l3num(const struct nf_conn *ct)
- {
- return ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num;
- }
复制代码 |
|