转:http://blog.csdn.net/nerdx/article/details/12656987
-
-
-
-
-
-
-
1.1 static inline struct ipq *ip_find(struct iphdr *iph, u32 user)
-
{
-
-
__u16 id = iph->id;
-
__u32 saddr = iph->saddr;
-
__u32 daddr = iph->daddr;
-
__u8 protocol = iph->protocol;
-
-
unsigned int hash = ipqhashfn(id, saddr, daddr, protocol);
-
struct ipq *qp;
-
-
read_lock(&ipfrag_lock);
-
-
for(qp = ipq_hash[hash]; qp; qp = qp->next) {
-
if(qp->id == id &&
-
qp->saddr == saddr &&
-
qp->daddr == daddr &&
-
qp->protocol == protocol &&
-
qp->user == user) {
-
atomic_inc(&qp->refcnt);
-
read_unlock(&ipfrag_lock);
-
return qp;
-
}
-
}
-
read_unlock(&ipfrag_lock);
-
-
return ip_frag_create(hash, iph, user);
-
}
-
-
-
-
1.2 static struct ipq *ip_frag_create(unsigned hash, struct iphdr *iph, u32 user)
-
{
-
struct ipq *qp;
-
-
if ((qp = frag_alloc_queue()) == NULL)
-
goto out_nomem;
-
-
qp->protocol = iph->protocol;
-
qp->last_in = 0;
-
qp->id = iph->id;
-
qp->saddr = iph->saddr;
-
qp->daddr = iph->daddr;
-
-
qp->user = user;
-
-
qp->len = 0;
-
qp->meat = 0;
-
qp->fragments = NULL;
-
qp->iif = 0;
-
-
init_timer(&qp->timer);
-
qp->timer.data = (unsigned long) qp;
-
qp->timer.function = ip_expire;
-
spin_lock_init(&qp->lock);
-
atomic_set(&qp->refcnt, 1);
-
-
return ip_frag_intern(hash, qp);
-
-
out_nomem:
-
NETDEBUG(if (net_ratelimit()) printk(KERN_ERR "ip_frag_create: no memory left !\n"));
-
return NULL;
-
}
-
-
-
-
-
-
-
-
1.3 static struct ipq *ip_frag_intern(unsigned int hash, struct ipq *qp_in)
-
{
-
struct ipq *qp;
-
-
write_lock(&ipfrag_lock);
-
-
qp = qp_in;
-
-
if (!mod_timer(&qp->timer, jiffies + sysctl_ipfrag_time))
-
atomic_inc(&qp->refcnt);
-
-
-
atomic_inc(&qp->refcnt);
-
if((qp->next = ipq_hash[hash]) != NULL)
-
qp->next->pprev = &qp->next;
-
ipq_hash[hash] = qp;
-
qp->pprev = &ipq_hash[hash];
-
-
INIT_LIST_HEAD(&qp->lru_list);
-
list_add_tail(&qp->lru_list, &ipq_lru_list);
-
ip_frag_nqueues++;
-
write_unlock(&ipfrag_lock);
-
return qp;
-
}
-
-
-
-
-
-
-
-
1.4 static void ip_expire(unsigned long arg)
-
{
-
struct ipq *qp = (struct ipq *) arg;
-
-
spin_lock(&qp->lock);
-
-
if (qp->last_in & COMPLETE)
-
goto out;
-
-
ipq_kill(qp);
-
-
if ((qp->last_in&FIRST_IN) && qp->fragments != NULL) {
-
struct sk_buff *head = qp->fragments;
-
if ((head->dev = dev_get_by_index(qp->iif)) != NULL) {
-
icmp_send(head, ICMP_TIME_EXCEEDED, ICMP_EXC_FRAGTIME, 0);
-
dev_put(head->dev);
-
}
-
}
-
out:
-
spin_unlock(&qp->lock);
-
ipq_put(qp, NULL);
-
}
-
阅读(989) | 评论(0) | 转发(0) |