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>
This commit is contained in:
@@ -72,6 +72,7 @@ struct frag_queue
|
||||
struct inet_frag_queue q;
|
||||
|
||||
__be32 id; /* fragment id */
|
||||
u32 user;
|
||||
struct in6_addr saddr;
|
||||
struct in6_addr daddr;
|
||||
|
||||
@@ -141,7 +142,7 @@ int ip6_frag_match(struct inet_frag_queue *q, void *a)
|
||||
struct ip6_create_arg *arg = a;
|
||||
|
||||
fq = container_of(q, struct frag_queue, q);
|
||||
return (fq->id == arg->id &&
|
||||
return (fq->id == arg->id && fq->user == arg->user &&
|
||||
ipv6_addr_equal(&fq->saddr, arg->src) &&
|
||||
ipv6_addr_equal(&fq->daddr, arg->dst));
|
||||
}
|
||||
@@ -163,6 +164,7 @@ void ip6_frag_init(struct inet_frag_queue *q, void *a)
|
||||
struct ip6_create_arg *arg = a;
|
||||
|
||||
fq->id = arg->id;
|
||||
fq->user = arg->user;
|
||||
ipv6_addr_copy(&fq->saddr, arg->src);
|
||||
ipv6_addr_copy(&fq->daddr, arg->dst);
|
||||
}
|
||||
@@ -243,6 +245,7 @@ fq_find(struct net *net, __be32 id, struct in6_addr *src, struct in6_addr *dst,
|
||||
unsigned int hash;
|
||||
|
||||
arg.id = id;
|
||||
arg.user = IP6_DEFRAG_LOCAL_DELIVER;
|
||||
arg.src = src;
|
||||
arg.dst = dst;
|
||||
|
||||
|
Reference in New Issue
Block a user