diff options
| author | Nikolay Aleksandrov <nikolay@redhat.com> | 2014-08-01 06:29:47 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2014-08-02 18:31:31 -0400 |
| commit | 2e404f632f44979ddf0ce0808a438249a72d7015 (patch) | |
| tree | ad03dac0a0596292475d7ac25b99c79a3499ee0d | |
| parent | f926e23660d52601089222cb4755aabc693ca390 (diff) | |
inet: frags: use INET_FRAG_EVICTED to prevent icmp messages
Now that we have INET_FRAG_EVICTED we might as well use it to stop
sending icmp messages in the "frag_expire" functions instead of
stripping INET_FRAG_FIRST_IN from their flags when evicting.
Also fix the comment style in ip6_expire_frag_queue().
Signed-off-by: Nikolay Aleksandrov <nikolay@redhat.com>
Reviewed-by: Florian Westphal <fw@strlen.de>
Signed-off-by: David S. Miller <davem@davemloft.net>
| -rw-r--r-- | net/ipv4/inet_fragment.c | 2 | ||||
| -rw-r--r-- | net/ipv4/ip_fragment.c | 14 | ||||
| -rw-r--r-- | net/ipv6/reassembly.c | 15 |
3 files changed, 15 insertions, 16 deletions
diff --git a/net/ipv4/inet_fragment.c b/net/ipv4/inet_fragment.c index fa49916c23a0..4baa76c60398 100644 --- a/net/ipv4/inet_fragment.c +++ b/net/ipv4/inet_fragment.c | |||
| @@ -151,8 +151,6 @@ evict_again: | |||
| 151 | goto evict_again; | 151 | goto evict_again; |
| 152 | } | 152 | } |
| 153 | 153 | ||
| 154 | /* suppress xmit of (icmp) error packet */ | ||
| 155 | fq->flags &= ~INET_FRAG_FIRST_IN; | ||
| 156 | fq->flags |= INET_FRAG_EVICTED; | 154 | fq->flags |= INET_FRAG_EVICTED; |
| 157 | hlist_del(&fq->list); | 155 | hlist_del(&fq->list); |
| 158 | hlist_add_head(&fq->list, &expired); | 156 | hlist_add_head(&fq->list, &expired); |
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c index 6fce1ecc5bca..cb56bcc1eee2 100644 --- a/net/ipv4/ip_fragment.c +++ b/net/ipv4/ip_fragment.c | |||
| @@ -189,16 +189,18 @@ static void ip_expire(unsigned long arg) | |||
| 189 | goto out; | 189 | goto out; |
| 190 | 190 | ||
| 191 | ipq_kill(qp); | 191 | ipq_kill(qp); |
| 192 | |||
| 193 | if (!(qp->q.flags & INET_FRAG_EVICTED)) | ||
| 194 | IP_INC_STATS_BH(net, IPSTATS_MIB_REASMTIMEOUT); | ||
| 195 | IP_INC_STATS_BH(net, IPSTATS_MIB_REASMFAILS); | 192 | IP_INC_STATS_BH(net, IPSTATS_MIB_REASMFAILS); |
| 196 | 193 | ||
| 197 | if ((qp->q.flags & INET_FRAG_FIRST_IN) && qp->q.fragments != NULL) { | 194 | if (!(qp->q.flags & INET_FRAG_EVICTED)) { |
| 198 | struct sk_buff *head = qp->q.fragments; | 195 | struct sk_buff *head = qp->q.fragments; |
| 199 | const struct iphdr *iph; | 196 | const struct iphdr *iph; |
| 200 | int err; | 197 | int err; |
| 201 | 198 | ||
| 199 | IP_INC_STATS_BH(net, IPSTATS_MIB_REASMTIMEOUT); | ||
| 200 | |||
| 201 | if (!(qp->q.flags & INET_FRAG_FIRST_IN) || !qp->q.fragments) | ||
| 202 | goto out; | ||
| 203 | |||
| 202 | rcu_read_lock(); | 204 | rcu_read_lock(); |
| 203 | head->dev = dev_get_by_index_rcu(net, qp->iif); | 205 | head->dev = dev_get_by_index_rcu(net, qp->iif); |
| 204 | if (!head->dev) | 206 | if (!head->dev) |
| @@ -211,8 +213,7 @@ static void ip_expire(unsigned long arg) | |||
| 211 | if (err) | 213 | if (err) |
| 212 | goto out_rcu_unlock; | 214 | goto out_rcu_unlock; |
| 213 | 215 | ||
| 214 | /* | 216 | /* Only an end host needs to send an ICMP |
| 215 | * Only an end host needs to send an ICMP | ||
| 216 | * "Fragment Reassembly Timeout" message, per RFC792. | 217 | * "Fragment Reassembly Timeout" message, per RFC792. |
| 217 | */ | 218 | */ |
| 218 | if (qp->user == IP_DEFRAG_AF_PACKET || | 219 | if (qp->user == IP_DEFRAG_AF_PACKET || |
| @@ -221,7 +222,6 @@ static void ip_expire(unsigned long arg) | |||
| 221 | (skb_rtable(head)->rt_type != RTN_LOCAL))) | 222 | (skb_rtable(head)->rt_type != RTN_LOCAL))) |
| 222 | goto out_rcu_unlock; | 223 | goto out_rcu_unlock; |
| 223 | 224 | ||
| 224 | |||
| 225 | /* Send an ICMP "Fragment Reassembly Timeout" message. */ | 225 | /* Send an ICMP "Fragment Reassembly Timeout" message. */ |
| 226 | icmp_send(head, ICMP_TIME_EXCEEDED, ICMP_EXC_FRAGTIME, 0); | 226 | icmp_send(head, ICMP_TIME_EXCEEDED, ICMP_EXC_FRAGTIME, 0); |
| 227 | out_rcu_unlock: | 227 | out_rcu_unlock: |
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c index b4baceed0d0d..beb6872a8fa5 100644 --- a/net/ipv6/reassembly.c +++ b/net/ipv6/reassembly.c | |||
| @@ -141,19 +141,20 @@ void ip6_expire_frag_queue(struct net *net, struct frag_queue *fq, | |||
| 141 | if (!dev) | 141 | if (!dev) |
| 142 | goto out_rcu_unlock; | 142 | goto out_rcu_unlock; |
| 143 | 143 | ||
| 144 | if (!(fq->q.flags & INET_FRAG_EVICTED)) | ||
| 145 | IP6_INC_STATS_BH(net, __in6_dev_get(dev), | ||
| 146 | IPSTATS_MIB_REASMTIMEOUT); | ||
| 147 | IP6_INC_STATS_BH(net, __in6_dev_get(dev), IPSTATS_MIB_REASMFAILS); | 144 | IP6_INC_STATS_BH(net, __in6_dev_get(dev), IPSTATS_MIB_REASMFAILS); |
| 148 | 145 | ||
| 146 | if (fq->q.flags & INET_FRAG_EVICTED) | ||
| 147 | goto out_rcu_unlock; | ||
| 148 | |||
| 149 | IP6_INC_STATS_BH(net, __in6_dev_get(dev), IPSTATS_MIB_REASMTIMEOUT); | ||
| 150 | |||
| 149 | /* Don't send error if the first segment did not arrive. */ | 151 | /* Don't send error if the first segment did not arrive. */ |
| 150 | if (!(fq->q.flags & INET_FRAG_FIRST_IN) || !fq->q.fragments) | 152 | if (!(fq->q.flags & INET_FRAG_FIRST_IN) || !fq->q.fragments) |
| 151 | goto out_rcu_unlock; | 153 | goto out_rcu_unlock; |
| 152 | 154 | ||
| 153 | /* | 155 | /* But use as source device on which LAST ARRIVED |
| 154 | But use as source device on which LAST ARRIVED | 156 | * segment was received. And do not use fq->dev |
| 155 | segment was received. And do not use fq->dev | 157 | * pointer directly, device might already disappeared. |
| 156 | pointer directly, device might already disappeared. | ||
| 157 | */ | 158 | */ |
| 158 | fq->q.fragments->dev = dev; | 159 | fq->q.fragments->dev = dev; |
| 159 | icmpv6_send(fq->q.fragments, ICMPV6_TIME_EXCEED, ICMPV6_EXC_FRAGTIME, 0); | 160 | icmpv6_send(fq->q.fragments, ICMPV6_TIME_EXCEED, ICMPV6_EXC_FRAGTIME, 0); |
