diff options
author | Patrick McHardy <kaber@trash.net> | 2009-12-15 16:59:18 +0100 |
---|---|---|
committer | Patrick McHardy <kaber@trash.net> | 2009-12-15 16:59:18 +0100 |
commit | 0b5ccb2ee250136dd7385b1c7da28417d0d4d32d (patch) | |
tree | b0630141672471d5c800867cd8dbee425308bc73 /net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c | |
parent | 9abfe315de96aa5c9878b2f627542bc54901c6e9 (diff) | |
download | kernel_samsung_smdk4412-0b5ccb2ee250136dd7385b1c7da28417d0d4d32d.zip kernel_samsung_smdk4412-0b5ccb2ee250136dd7385b1c7da28417d0d4d32d.tar.gz kernel_samsung_smdk4412-0b5ccb2ee250136dd7385b1c7da28417d0d4d32d.tar.bz2 |
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.c | 13 |
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 5f2ec20..c0a82fe 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; |