Skip to content

Commit 399d140

Browse files
edumazetdavem330
authored andcommitted
inet: frags: get rif of inet_frag_evicting()
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 ec4fbd6 ("inet: frag: release spinlock before calling icmp_send()") Signed-off-by: Eric Dumazet <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 6befe4a commit 399d140

File tree

3 files changed

+32
-42
lines changed

3 files changed

+32
-42
lines changed

include/net/inet_frag.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -119,11 +119,6 @@ static inline void inet_frag_put(struct inet_frag_queue *q)
119119
inet_frag_destroy(q);
120120
}
121121

122-
static inline bool inet_frag_evicting(struct inet_frag_queue *q)
123-
{
124-
return false;
125-
}
126-
127122
/* Memory Tracking Functions. */
128123

129124
static inline int frag_mem_limit(struct netns_frags *nf)

net/ipv4/ip_fragment.c

Lines changed: 32 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,11 @@ static bool frag_expire_skip_icmp(u32 user)
143143
static void ip_expire(struct timer_list *t)
144144
{
145145
struct inet_frag_queue *frag = from_timer(frag, t, timer);
146-
struct ipq *qp;
146+
struct sk_buff *clone, *head;
147+
const struct iphdr *iph;
147148
struct net *net;
149+
struct ipq *qp;
150+
int err;
148151

149152
qp = container_of(frag, struct ipq, q);
150153
net = container_of(qp->q.net, struct net, ipv4.frags);
@@ -158,45 +161,41 @@ static void ip_expire(struct timer_list *t)
158161
ipq_kill(qp);
159162
__IP_INC_STATS(net, IPSTATS_MIB_REASMFAILS);
160163

161-
if (!inet_frag_evicting(&qp->q)) {
162-
struct sk_buff *clone, *head = qp->q.fragments;
163-
const struct iphdr *iph;
164-
int err;
164+
head = qp->q.fragments;
165165

166-
__IP_INC_STATS(net, IPSTATS_MIB_REASMTIMEOUT);
166+
__IP_INC_STATS(net, IPSTATS_MIB_REASMTIMEOUT);
167167

168-
if (!(qp->q.flags & INET_FRAG_FIRST_IN) || !qp->q.fragments)
169-
goto out;
168+
if (!(qp->q.flags & INET_FRAG_FIRST_IN) || !head)
169+
goto out;
170170

171-
head->dev = dev_get_by_index_rcu(net, qp->iif);
172-
if (!head->dev)
173-
goto out;
171+
head->dev = dev_get_by_index_rcu(net, qp->iif);
172+
if (!head->dev)
173+
goto out;
174174

175175

176-
/* skb has no dst, perform route lookup again */
177-
iph = ip_hdr(head);
178-
err = ip_route_input_noref(head, iph->daddr, iph->saddr,
176+
/* skb has no dst, perform route lookup again */
177+
iph = ip_hdr(head);
178+
err = ip_route_input_noref(head, iph->daddr, iph->saddr,
179179
iph->tos, head->dev);
180-
if (err)
181-
goto out;
180+
if (err)
181+
goto out;
182182

183-
/* Only an end host needs to send an ICMP
184-
* "Fragment Reassembly Timeout" message, per RFC792.
185-
*/
186-
if (frag_expire_skip_icmp(qp->q.key.v4.user) &&
187-
(skb_rtable(head)->rt_type != RTN_LOCAL))
188-
goto out;
189-
190-
clone = skb_clone(head, GFP_ATOMIC);
191-
192-
/* Send an ICMP "Fragment Reassembly Timeout" message. */
193-
if (clone) {
194-
spin_unlock(&qp->q.lock);
195-
icmp_send(clone, ICMP_TIME_EXCEEDED,
196-
ICMP_EXC_FRAGTIME, 0);
197-
consume_skb(clone);
198-
goto out_rcu_unlock;
199-
}
183+
/* Only an end host needs to send an ICMP
184+
* "Fragment Reassembly Timeout" message, per RFC792.
185+
*/
186+
if (frag_expire_skip_icmp(qp->q.key.v4.user) &&
187+
(skb_rtable(head)->rt_type != RTN_LOCAL))
188+
goto out;
189+
190+
clone = skb_clone(head, GFP_ATOMIC);
191+
192+
/* Send an ICMP "Fragment Reassembly Timeout" message. */
193+
if (clone) {
194+
spin_unlock(&qp->q.lock);
195+
icmp_send(clone, ICMP_TIME_EXCEEDED,
196+
ICMP_EXC_FRAGTIME, 0);
197+
consume_skb(clone);
198+
goto out_rcu_unlock;
200199
}
201200
out:
202201
spin_unlock(&qp->q.lock);

net/ipv6/reassembly.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -106,10 +106,6 @@ void ip6_expire_frag_queue(struct net *net, struct frag_queue *fq)
106106
goto out_rcu_unlock;
107107

108108
__IP6_INC_STATS(net, __in6_dev_get(dev), IPSTATS_MIB_REASMFAILS);
109-
110-
if (inet_frag_evicting(&fq->q))
111-
goto out_rcu_unlock;
112-
113109
__IP6_INC_STATS(net, __in6_dev_get(dev), IPSTATS_MIB_REASMTIMEOUT);
114110

115111
/* Don't send error if the first segment did not arrive. */

0 commit comments

Comments
 (0)