aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/ipv6.h7
-rw-r--r--include/net/netfilter/ipv6/nf_conntrack_ipv6.h2
-rw-r--r--net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c13
-rw-r--r--net/ipv6/netfilter/nf_conntrack_reasm.c7
-rw-r--r--net/ipv6/reassembly.c5
5 files changed, 27 insertions, 7 deletions
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index 92db8617d188..d6916035bcea 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -350,8 +350,15 @@ static inline int ipv6_prefix_equal(const struct in6_addr *a1,
350 350
351struct inet_frag_queue; 351struct inet_frag_queue;
352 352
353enum ip6_defrag_users {
354 IP6_DEFRAG_LOCAL_DELIVER,
355 IP6_DEFRAG_CONNTRACK_IN,
356 IP6_DEFRAG_CONNTRACK_OUT,
357};
358
353struct ip6_create_arg { 359struct ip6_create_arg {
354 __be32 id; 360 __be32 id;
361 u32 user;
355 struct in6_addr *src; 362 struct in6_addr *src;
356 struct in6_addr *dst; 363 struct in6_addr *dst;
357}; 364};
diff --git a/include/net/netfilter/ipv6/nf_conntrack_ipv6.h b/include/net/netfilter/ipv6/nf_conntrack_ipv6.h
index abc55ad75c2b..1ee717eb5b09 100644
--- a/include/net/netfilter/ipv6/nf_conntrack_ipv6.h
+++ b/include/net/netfilter/ipv6/nf_conntrack_ipv6.h
@@ -9,7 +9,7 @@ extern struct nf_conntrack_l4proto nf_conntrack_l4proto_icmpv6;
9 9
10extern int nf_ct_frag6_init(void); 10extern int nf_ct_frag6_init(void);
11extern void nf_ct_frag6_cleanup(void); 11extern void nf_ct_frag6_cleanup(void);
12extern struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb); 12extern struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb, u32 user);
13extern void nf_ct_frag6_output(unsigned int hooknum, struct sk_buff *skb, 13extern void nf_ct_frag6_output(unsigned int hooknum, struct sk_buff *skb,
14 struct net_device *in, 14 struct net_device *in,
15 struct net_device *out, 15 struct net_device *out,
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
index 5f2ec208a8c3..c0a82fe78321 100644
--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
@@ -187,6 +187,16 @@ out:
187 return nf_conntrack_confirm(skb); 187 return nf_conntrack_confirm(skb);
188} 188}
189 189
190static enum ip6_defrag_users nf_ct6_defrag_user(unsigned int hooknum,
191 struct sk_buff *skb)
192{
193 if (hooknum == NF_INET_PRE_ROUTING)
194 return IP6_DEFRAG_CONNTRACK_IN;
195 else
196 return IP6_DEFRAG_CONNTRACK_OUT;
197
198}
199
190static unsigned int ipv6_defrag(unsigned int hooknum, 200static unsigned int ipv6_defrag(unsigned int hooknum,
191 struct sk_buff *skb, 201 struct sk_buff *skb,
192 const struct net_device *in, 202 const struct net_device *in,
@@ -199,8 +209,7 @@ static unsigned int ipv6_defrag(unsigned int hooknum,
199 if (skb->nfct) 209 if (skb->nfct)
200 return NF_ACCEPT; 210 return NF_ACCEPT;
201 211
202 reasm = nf_ct_frag6_gather(skb); 212 reasm = nf_ct_frag6_gather(skb, nf_ct6_defrag_user(hooknum, skb));
203
204 /* queued */ 213 /* queued */
205 if (reasm == NULL) 214 if (reasm == NULL)
206 return NF_STOLEN; 215 return NF_STOLEN;
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
index e0b9424fa1b2..312c20adc83f 100644
--- a/net/ipv6/netfilter/nf_conntrack_reasm.c
+++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
@@ -168,13 +168,14 @@ out:
168/* Creation primitives. */ 168/* Creation primitives. */
169 169
170static __inline__ struct nf_ct_frag6_queue * 170static __inline__ struct nf_ct_frag6_queue *
171fq_find(__be32 id, struct in6_addr *src, struct in6_addr *dst) 171fq_find(__be32 id, u32 user, struct in6_addr *src, struct in6_addr *dst)
172{ 172{
173 struct inet_frag_queue *q; 173 struct inet_frag_queue *q;
174 struct ip6_create_arg arg; 174 struct ip6_create_arg arg;
175 unsigned int hash; 175 unsigned int hash;
176 176
177 arg.id = id; 177 arg.id = id;
178 arg.user = user;
178 arg.src = src; 179 arg.src = src;
179 arg.dst = dst; 180 arg.dst = dst;
180 181
@@ -559,7 +560,7 @@ find_prev_fhdr(struct sk_buff *skb, u8 *prevhdrp, int *prevhoff, int *fhoff)
559 return 0; 560 return 0;
560} 561}
561 562
562struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb) 563struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb, u32 user)
563{ 564{
564 struct sk_buff *clone; 565 struct sk_buff *clone;
565 struct net_device *dev = skb->dev; 566 struct net_device *dev = skb->dev;
@@ -605,7 +606,7 @@ struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb)
605 if (atomic_read(&nf_init_frags.mem) > nf_init_frags.high_thresh) 606 if (atomic_read(&nf_init_frags.mem) > nf_init_frags.high_thresh)
606 nf_ct_frag6_evictor(); 607 nf_ct_frag6_evictor();
607 608
608 fq = fq_find(fhdr->identification, &hdr->saddr, &hdr->daddr); 609 fq = fq_find(fhdr->identification, user, &hdr->saddr, &hdr->daddr);
609 if (fq == NULL) { 610 if (fq == NULL) {
610 pr_debug("Can't find and can't create new queue\n"); 611 pr_debug("Can't find and can't create new queue\n");
611 goto ret_orig; 612 goto ret_orig;
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c
index 4d98549a6868..3b3a95607125 100644
--- a/net/ipv6/reassembly.c
+++ b/net/ipv6/reassembly.c
@@ -72,6 +72,7 @@ struct frag_queue
72 struct inet_frag_queue q; 72 struct inet_frag_queue q;
73 73
74 __be32 id; /* fragment id */ 74 __be32 id; /* fragment id */
75 u32 user;
75 struct in6_addr saddr; 76 struct in6_addr saddr;
76 struct in6_addr daddr; 77 struct in6_addr daddr;
77 78
@@ -141,7 +142,7 @@ int ip6_frag_match(struct inet_frag_queue *q, void *a)
141 struct ip6_create_arg *arg = a; 142 struct ip6_create_arg *arg = a;
142 143
143 fq = container_of(q, struct frag_queue, q); 144 fq = container_of(q, struct frag_queue, q);
144 return (fq->id == arg->id && 145 return (fq->id == arg->id && fq->user == arg->user &&
145 ipv6_addr_equal(&fq->saddr, arg->src) && 146 ipv6_addr_equal(&fq->saddr, arg->src) &&
146 ipv6_addr_equal(&fq->daddr, arg->dst)); 147 ipv6_addr_equal(&fq->daddr, arg->dst));
147} 148}
@@ -163,6 +164,7 @@ void ip6_frag_init(struct inet_frag_queue *q, void *a)
163 struct ip6_create_arg *arg = a; 164 struct ip6_create_arg *arg = a;
164 165
165 fq->id = arg->id; 166 fq->id = arg->id;
167 fq->user = arg->user;
166 ipv6_addr_copy(&fq->saddr, arg->src); 168 ipv6_addr_copy(&fq->saddr, arg->src);
167 ipv6_addr_copy(&fq->daddr, arg->dst); 169 ipv6_addr_copy(&fq->daddr, arg->dst);
168} 170}
@@ -243,6 +245,7 @@ fq_find(struct net *net, __be32 id, struct in6_addr *src, struct in6_addr *dst,
243 unsigned int hash; 245 unsigned int hash;
244 246
245 arg.id = id; 247 arg.id = id;
248 arg.user = IP6_DEFRAG_LOCAL_DELIVER;
246 arg.src = src; 249 arg.src = src;
247 arg.dst = dst; 250 arg.dst = dst;
248 251