inet: frags: get rif of inet_frag_evicting()
commit 399d1404be660d355192ff4df5ccc3f4159ec1e4 upstream. This refactors ip_expire() since one indentation level is removed. Note: in the future, we should try hard to avoid the skb_clone() since this is a serious performance cost. Under DDOS, the ICMP message wont be sent because of rate limits. Fact that ip6_expire_frag_queue() does not use skb_clone() is disturbing too. Presumably IPv6 should have the same issue than the one we fixed in commit ec4fbd64751d ("inet: frag: release spinlock before calling icmp_send()") Signed-off-by: Eric Dumazet <edumazet@google.com> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Mao Wenan <maowenan@huawei.com> [bwh: Backported to 4.4: adjust context] Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
cf2b9e68a6
commit
b047c796de
3 changed files with 30 additions and 40 deletions
|
@ -118,11 +118,6 @@ static inline void inet_frag_put(struct inet_frag_queue *q)
|
||||||
inet_frag_destroy(q);
|
inet_frag_destroy(q);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool inet_frag_evicting(struct inet_frag_queue *q)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Memory Tracking Functions. */
|
/* Memory Tracking Functions. */
|
||||||
|
|
||||||
static inline int frag_mem_limit(struct netns_frags *nf)
|
static inline int frag_mem_limit(struct netns_frags *nf)
|
||||||
|
|
|
@ -143,8 +143,11 @@ static bool frag_expire_skip_icmp(u32 user)
|
||||||
*/
|
*/
|
||||||
static void ip_expire(unsigned long arg)
|
static void ip_expire(unsigned long arg)
|
||||||
{
|
{
|
||||||
struct ipq *qp;
|
struct sk_buff *clone, *head;
|
||||||
|
const struct iphdr *iph;
|
||||||
struct net *net;
|
struct net *net;
|
||||||
|
struct ipq *qp;
|
||||||
|
int err;
|
||||||
|
|
||||||
qp = container_of((struct inet_frag_queue *) arg, struct ipq, q);
|
qp = container_of((struct inet_frag_queue *) arg, struct ipq, q);
|
||||||
net = container_of(qp->q.net, struct net, ipv4.frags);
|
net = container_of(qp->q.net, struct net, ipv4.frags);
|
||||||
|
@ -158,14 +161,11 @@ static void ip_expire(unsigned long arg)
|
||||||
ipq_kill(qp);
|
ipq_kill(qp);
|
||||||
IP_INC_STATS_BH(net, IPSTATS_MIB_REASMFAILS);
|
IP_INC_STATS_BH(net, IPSTATS_MIB_REASMFAILS);
|
||||||
|
|
||||||
if (!inet_frag_evicting(&qp->q)) {
|
head = qp->q.fragments;
|
||||||
struct sk_buff *clone, *head = qp->q.fragments;
|
|
||||||
const struct iphdr *iph;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
IP_INC_STATS_BH(net, IPSTATS_MIB_REASMTIMEOUT);
|
IP_INC_STATS_BH(net, IPSTATS_MIB_REASMTIMEOUT);
|
||||||
|
|
||||||
if (!(qp->q.flags & INET_FRAG_FIRST_IN) || !qp->q.fragments)
|
if (!(qp->q.flags & INET_FRAG_FIRST_IN) || !head)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
head->dev = dev_get_by_index_rcu(net, qp->iif);
|
head->dev = dev_get_by_index_rcu(net, qp->iif);
|
||||||
|
@ -197,7 +197,6 @@ static void ip_expire(unsigned long arg)
|
||||||
consume_skb(clone);
|
consume_skb(clone);
|
||||||
goto out_rcu_unlock;
|
goto out_rcu_unlock;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
out:
|
out:
|
||||||
spin_unlock(&qp->q.lock);
|
spin_unlock(&qp->q.lock);
|
||||||
out_rcu_unlock:
|
out_rcu_unlock:
|
||||||
|
|
|
@ -106,10 +106,6 @@ void ip6_expire_frag_queue(struct net *net, struct frag_queue *fq)
|
||||||
goto out_rcu_unlock;
|
goto out_rcu_unlock;
|
||||||
|
|
||||||
IP6_INC_STATS_BH(net, __in6_dev_get(dev), IPSTATS_MIB_REASMFAILS);
|
IP6_INC_STATS_BH(net, __in6_dev_get(dev), IPSTATS_MIB_REASMFAILS);
|
||||||
|
|
||||||
if (inet_frag_evicting(&fq->q))
|
|
||||||
goto out_rcu_unlock;
|
|
||||||
|
|
||||||
IP6_INC_STATS_BH(net, __in6_dev_get(dev), IPSTATS_MIB_REASMTIMEOUT);
|
IP6_INC_STATS_BH(net, __in6_dev_get(dev), IPSTATS_MIB_REASMTIMEOUT);
|
||||||
|
|
||||||
/* Don't send error if the first segment did not arrive. */
|
/* Don't send error if the first segment did not arrive. */
|
||||||
|
|
Loading…
Add table
Reference in a new issue