diff options
author | Amerigo Wang <amwang@redhat.com> | 2012-09-18 12:50:09 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-09-19 17:23:28 -0400 |
commit | b836c99fd6c9dfe52a69fa0ba36ec918f80ce02a (patch) | |
tree | cb3459103371712b73c8b7695cf05d8f936480a2 /include | |
parent | c038a767cd697238b09f7a4ea5a504b4891774e9 (diff) |
ipv6: unify conntrack reassembly expire code with standard one
Two years ago, Shan Wei tried to fix this:
http://patchwork.ozlabs.org/patch/43905/
The problem is that RFC2460 requires an ICMP Time
Exceeded -- Fragment Reassembly Time Exceeded message should be
sent to the source of that fragment, if the defragmentation
times out.
"
If insufficient fragments are received to complete reassembly of a
packet within 60 seconds of the reception of the first-arriving
fragment of that packet, reassembly of that packet must be
abandoned and all the fragments that have been received for that
packet must be discarded. If the first fragment (i.e., the one
with a Fragment Offset of zero) has been received, an ICMP Time
Exceeded -- Fragment Reassembly Time Exceeded message should be
sent to the source of that fragment.
"
As Herbert suggested, we could actually use the standard IPv6
reassembly code which follows RFC2460.
With this patch applied, I can see ICMP Time Exceeded sent
from the receiver when the sender sent out 3/4 fragmented
IPv6 UDP packet.
Cc: Herbert Xu <herbert@gondor.apana.org.au>
Cc: Michal Kubeček <mkubecek@suse.cz>
Cc: David Miller <davem@davemloft.net>
Cc: Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org>
Cc: Patrick McHardy <kaber@trash.net>
Cc: Pablo Neira Ayuso <pablo@netfilter.org>
Cc: netfilter-devel@vger.kernel.org
Signed-off-by: Cong Wang <amwang@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include')
-rw-r--r-- | include/net/ipv6.h | 19 |
1 files changed, 19 insertions, 0 deletions
diff --git a/include/net/ipv6.h b/include/net/ipv6.h index 9bed5d483405..81d4455f6e14 100644 --- a/include/net/ipv6.h +++ b/include/net/ipv6.h | |||
@@ -411,6 +411,25 @@ struct ip6_create_arg { | |||
411 | void ip6_frag_init(struct inet_frag_queue *q, void *a); | 411 | void ip6_frag_init(struct inet_frag_queue *q, void *a); |
412 | bool ip6_frag_match(struct inet_frag_queue *q, void *a); | 412 | bool ip6_frag_match(struct inet_frag_queue *q, void *a); |
413 | 413 | ||
414 | /* | ||
415 | * Equivalent of ipv4 struct ip | ||
416 | */ | ||
417 | struct frag_queue { | ||
418 | struct inet_frag_queue q; | ||
419 | |||
420 | __be32 id; /* fragment id */ | ||
421 | u32 user; | ||
422 | struct in6_addr saddr; | ||
423 | struct in6_addr daddr; | ||
424 | |||
425 | int iif; | ||
426 | unsigned int csum; | ||
427 | __u16 nhoffset; | ||
428 | }; | ||
429 | |||
430 | void ip6_expire_frag_queue(struct net *net, struct frag_queue *fq, | ||
431 | struct inet_frags *frags); | ||
432 | |||
414 | static inline bool ipv6_addr_any(const struct in6_addr *a) | 433 | static inline bool ipv6_addr_any(const struct in6_addr *a) |
415 | { | 434 | { |
416 | #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64 | 435 | #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64 |