Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6b102865 authored by Amerigo Wang's avatar Amerigo Wang Committed by David S. Miller
Browse files

ipv6: unify fragment thresh handling code



Cc: Herbert Xu <herbert@gondor.apana.org.au>
Cc: Michal Kubeček <mkubecek@suse.cz>
Cc: David Miller <davem@davemloft.net>
Signed-off-by: default avatarCong Wang <amwang@redhat.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent d4915c08
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -61,7 +61,7 @@ void inet_frags_exit_net(struct netns_frags *nf, struct inet_frags *f);
void inet_frag_kill(struct inet_frag_queue *q, struct inet_frags *f);
void inet_frag_destroy(struct inet_frag_queue *q,
				struct inet_frags *f, int *work);
int inet_frag_evictor(struct netns_frags *nf, struct inet_frags *f);
int inet_frag_evictor(struct netns_frags *nf, struct inet_frags *f, bool force);
struct inet_frag_queue *inet_frag_find(struct netns_frags *nf,
		struct inet_frags *f, void *key, unsigned int hash)
	__releases(&f->lock);
+7 −2
Original line number Diff line number Diff line
@@ -89,7 +89,7 @@ void inet_frags_exit_net(struct netns_frags *nf, struct inet_frags *f)
	nf->low_thresh = 0;

	local_bh_disable();
	inet_frag_evictor(nf, f);
	inet_frag_evictor(nf, f, true);
	local_bh_enable();
}
EXPORT_SYMBOL(inet_frags_exit_net);
@@ -158,11 +158,16 @@ void inet_frag_destroy(struct inet_frag_queue *q, struct inet_frags *f,
}
EXPORT_SYMBOL(inet_frag_destroy);

int inet_frag_evictor(struct netns_frags *nf, struct inet_frags *f)
int inet_frag_evictor(struct netns_frags *nf, struct inet_frags *f, bool force)
{
	struct inet_frag_queue *q;
	int work, evicted = 0;

	if (!force) {
		if (atomic_read(&nf->mem) <= nf->high_thresh)
			return 0;
	}

	work = atomic_read(&nf->mem) - nf->low_thresh;
	while (work > 0) {
		read_lock(&f->lock);
+2 −3
Original line number Diff line number Diff line
@@ -219,7 +219,7 @@ static void ip_evictor(struct net *net)
{
	int evicted;

	evicted = inet_frag_evictor(&net->ipv4.frags, &ip4_frags);
	evicted = inet_frag_evictor(&net->ipv4.frags, &ip4_frags, false);
	if (evicted)
		IP_ADD_STATS_BH(net, IPSTATS_MIB_REASMFAILS, evicted);
}
@@ -684,7 +684,6 @@ int ip_defrag(struct sk_buff *skb, u32 user)
	IP_INC_STATS_BH(net, IPSTATS_MIB_REASMREQDS);

	/* Start by cleaning up the memory. */
	if (atomic_read(&net->ipv4.frags.mem) > net->ipv4.frags.high_thresh)
	ip_evictor(net);

	/* Lookup (or create) queue header */
+3 −5
Original line number Diff line number Diff line
@@ -566,11 +566,9 @@ struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb, u32 user)
	hdr = ipv6_hdr(clone);
	fhdr = (struct frag_hdr *)skb_transport_header(clone);

	if (atomic_read(&net->nf_frag.frags.mem) > net->nf_frag.frags.high_thresh) {
	local_bh_disable();
		inet_frag_evictor(&net->nf_frag.frags, &nf_frags);
	inet_frag_evictor(&net->nf_frag.frags, &nf_frags, false);
	local_bh_enable();
	}

	fq = fq_find(net, fhdr->identification, user, &hdr->saddr, &hdr->daddr);
	if (fq == NULL) {
+5 −11
Original line number Diff line number Diff line
@@ -131,15 +131,6 @@ void ip6_frag_init(struct inet_frag_queue *q, void *a)
}
EXPORT_SYMBOL(ip6_frag_init);

static void ip6_evictor(struct net *net, struct inet6_dev *idev)
{
	int evicted;

	evicted = inet_frag_evictor(&net->ipv6.frags, &ip6_frags);
	if (evicted)
		IP6_ADD_STATS_BH(net, idev, IPSTATS_MIB_REASMFAILS, evicted);
}

void ip6_expire_frag_queue(struct net *net, struct frag_queue *fq,
			   struct inet_frags *frags)
{
@@ -515,6 +506,7 @@ static int ipv6_frag_rcv(struct sk_buff *skb)
	struct frag_queue *fq;
	const struct ipv6hdr *hdr = ipv6_hdr(skb);
	struct net *net = dev_net(skb_dst(skb)->dev);
	int evicted;

	IP6_INC_STATS_BH(net, ip6_dst_idev(skb_dst(skb)), IPSTATS_MIB_REASMREQDS);

@@ -539,8 +531,10 @@ static int ipv6_frag_rcv(struct sk_buff *skb)
		return 1;
	}

	if (atomic_read(&net->ipv6.frags.mem) > net->ipv6.frags.high_thresh)
		ip6_evictor(net, ip6_dst_idev(skb_dst(skb)));
	evicted = inet_frag_evictor(&net->ipv6.frags, &ip6_frags, false);
	if (evicted)
		IP6_ADD_STATS_BH(net, ip6_dst_idev(skb_dst(skb)),
				 IPSTATS_MIB_REASMFAILS, evicted);

	fq = fq_find(net, fhdr->identification, &hdr->saddr, &hdr->daddr);
	if (fq != NULL) {