- static inline struct ipq *ip_find(struct net *net, struct iphdr *iph, u32 user)
-
{
-
struct inet_frag_queue *q;
-
struct ip4_create_arg arg;
-
unsigned int hash;
-
-
arg.iph = iph;
-
arg.user = user;
/*
这里对获得了ip4_frags.lock的读锁,何时释放的呢?
答案是在inet_frag_find这个函数中。
这种锁的使用风格,我很不喜欢。为什么kernel会使用这种方式呢?
*/
-
read_lock(&ip4_frags.lock);
- /*
- 对于IP分片来说,使用IP头部信息中的identifier,源地址,目的地址,以及协议来计算hash值。一般来说,这 四个值基本上可以保证了IP分片的队列信息的唯一性。不过由于NAT设备的使用,就有可能将不同的分片队列混在 一起。在计算hash值上,还使用ip4_frags.rnd这一随机值。
- */
-
hash = ipqhashfn(iph->id, iph->saddr, iph->daddr, iph->protocol);
-
-
q = inet_frag_find(&net->ipv4.frags, &ip4_frags, &arg, hash);
-
if (q == NULL)
-
goto out_nomem;
/* 内核中实际上维护的变量类型为struct ipq,需要从其成员变量q,获得原来的struct ipq类型的地址 */
-
return container_of(q, struct ipq, q);
-
-
out_nomem:
-
LIMIT_NETDEBUG(KERN_ERR "ip_frag_create: no memory left !\n");
-
return NULL;
-
}