Ejemplo n.º 1
0
static __inline__ struct frag_queue *
fq_find(struct net *net, __be32 id, struct in6_addr *src, struct in6_addr *dst,
	struct inet6_dev *idev)
{
	struct inet_frag_queue *q;
	struct ip6_create_arg arg;
	unsigned int hash;

	arg.id = id;
	arg.user = IP6_DEFRAG_LOCAL_DELIVER;
	arg.src = src;
	arg.dst = dst;

	read_lock(&ip6_frags.lock);
	hash = ip6qhashfn(id, src, dst);

	q = inet_frag_find(&net->ipv6.frags, &ip6_frags, &arg, hash);
	if (q == NULL)
		goto oom;

	return container_of(q, struct frag_queue, q);

oom:
	IP6_INC_STATS_BH(idev, IPSTATS_MIB_REASMFAILS);
	return NULL;
}
Ejemplo n.º 2
0
static unsigned int ip6_hashfn(struct inet_frag_queue *q)
{
	struct frag_queue *fq;

	fq = container_of(q, struct frag_queue, q);
	return ip6qhashfn(fq->id, &fq->saddr, &fq->daddr);
}
static __inline__ struct nf_ct_frag6_queue *
fq_find(u32 id, struct in6_addr *src, struct in6_addr *dst)
{
	struct nf_ct_frag6_queue *fq;
	unsigned int hash = ip6qhashfn(id, src, dst);

	read_lock(&nf_ct_frag6_lock);
	for (fq = nf_ct_frag6_hash[hash]; fq; fq = fq->next) {
		if (fq->id == id && 
		    !ipv6_addr_cmp(src, &fq->saddr) &&
		    !ipv6_addr_cmp(dst, &fq->daddr)) {
			atomic_inc(&fq->refcnt);
			read_unlock(&nf_ct_frag6_lock);
			return fq;
		}
	}
	read_unlock(&nf_ct_frag6_lock);

	return nf_ct_frag6_create(hash, id, src, dst);
}
static void nf_ct_frag6_secret_rebuild(unsigned long dummy)
{
	unsigned long now = jiffies;
	int i;

	write_lock(&nf_ct_frag6_lock);
	get_random_bytes(&nf_ct_frag6_hash_rnd, sizeof(u32));
	for (i = 0; i < FRAG6Q_HASHSZ; i++) {
		struct nf_ct_frag6_queue *q;

		q = nf_ct_frag6_hash[i];
		while (q) {
			struct nf_ct_frag6_queue *next = q->next;
			unsigned int hval = ip6qhashfn(q->id,
						       &q->saddr,
						       &q->daddr);

			if (hval != i) {
				/* Unlink. */
				if (q->next)
					q->next->pprev = q->pprev;
				*q->pprev = q->next;

				/* Relink to new hash chain. */
				if ((q->next = nf_ct_frag6_hash[hval]) != NULL)
					q->next->pprev = &q->next;
				nf_ct_frag6_hash[hval] = q;
				q->pprev = &nf_ct_frag6_hash[hval];
			}

			q = next;
		}
	}
	write_unlock(&nf_ct_frag6_lock);

	mod_timer(&nf_ct_frag6_secret_timer, now + nf_ct_frag6_secret_interval);
}