aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2009-12-15 16:59:18 +0100
committerPatrick McHardy <kaber@trash.net>2009-12-15 16:59:18 +0100
commit0b5ccb2ee250136dd7385b1c7da28417d0d4d32d (patch)
treeb0630141672471d5c800867cd8dbee425308bc73 /net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
parent9abfe315de96aa5c9878b2f627542bc54901c6e9 (diff)
downloadlinux-0b5ccb2ee250136dd7385b1c7da28417d0d4d32d.tar.gz
ipv6: reassembly: use seperate reassembly queues for conntrack and local delivery
Currently the same reassembly queue might be used for packets reassembled by conntrack in different positions in the stack (PREROUTING/LOCAL_OUT), as well as local delivery. This can cause "packet jumps" when the fragment completing a reassembled packet is queued from a different position in the stack than the previous ones. Add a "user" identifier to the reassembly queue key to seperate the queues of each caller, similar to what we do for IPv4. Signed-off-by: Patrick McHardy <kaber@trash.net>
Diffstat (limited to 'net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c')
-rw-r--r--net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c13
1 files changed, 11 insertions, 2 deletions
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
index 5f2ec208a8c3a..c0a82fe783210 100644
--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
@@ -187,6 +187,16 @@ out:
return nf_conntrack_confirm(skb);
}
+static enum ip6_defrag_users nf_ct6_defrag_user(unsigned int hooknum,
+ struct sk_buff *skb)
+{
+ if (hooknum == NF_INET_PRE_ROUTING)
+ return IP6_DEFRAG_CONNTRACK_IN;
+ else
+ return IP6_DEFRAG_CONNTRACK_OUT;
+
+}
+
static unsigned int ipv6_defrag(unsigned int hooknum,
struct sk_buff *skb,
const struct net_device *in,
@@ -199,8 +209,7 @@ static unsigned int ipv6_defrag(unsigned int hooknum,
if (skb->nfct)
return NF_ACCEPT;
- reasm = nf_ct_frag6_gather(skb);
-
+ reasm = nf_ct_frag6_gather(skb, nf_ct6_defrag_user(hooknum, skb));
/* queued */
if (reasm == NULL)
return NF_STOLEN;