aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorChangli Gao <xiaosuo@gmail.com>2010-07-05 04:38:23 -0400
committerPatrick McHardy <kaber@trash.net>2010-07-05 04:38:23 -0400
commitea8fbe8f198edea19116d4b61267e12235513225 (patch)
treee9fae0d935a083b8db23dbe02e0bd1b61fe4fc2a /net
parent39827be26b36ef9cdbc661c92a269e0484cd9ef5 (diff)
netfilter: nf_conntrack_reasm: add fast path for in-order fragments
As the fragments are sent in order in most of OSes, such as Windows, Darwin and FreeBSD, it is likely the new fragments are at the end of the inet_frag_queue. In the fast path, we check if the skb at the end of the inet_frag_queue is the prev we expect. Signed-off-by: Changli Gao <xiaosuo@gmail.com> Signed-off-by: Patrick McHardy <kaber@trash.net>
Diffstat (limited to 'net')
-rw-r--r--net/ipv6/netfilter/nf_conntrack_reasm.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
index 9254008602d4..098a050a20b0 100644
--- a/net/ipv6/netfilter/nf_conntrack_reasm.c
+++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
@@ -269,6 +269,11 @@ static int nf_ct_frag6_queue(struct nf_ct_frag6_queue *fq, struct sk_buff *skb,
269 * in the chain of fragments so far. We must know where to put 269 * in the chain of fragments so far. We must know where to put
270 * this fragment, right? 270 * this fragment, right?
271 */ 271 */
272 prev = fq->q.fragments_tail;
273 if (!prev || NFCT_FRAG6_CB(prev)->offset < offset) {
274 next = NULL;
275 goto found;
276 }
272 prev = NULL; 277 prev = NULL;
273 for (next = fq->q.fragments; next != NULL; next = next->next) { 278 for (next = fq->q.fragments; next != NULL; next = next->next) {
274 if (NFCT_FRAG6_CB(next)->offset >= offset) 279 if (NFCT_FRAG6_CB(next)->offset >= offset)
@@ -276,6 +281,7 @@ static int nf_ct_frag6_queue(struct nf_ct_frag6_queue *fq, struct sk_buff *skb,
276 prev = next; 281 prev = next;
277 } 282 }
278 283
284found:
279 /* We found where to put this one. Check for overlap with 285 /* We found where to put this one. Check for overlap with
280 * preceding fragment, and, if needed, align things so that 286 * preceding fragment, and, if needed, align things so that
281 * any overlaps are eliminated. 287 * any overlaps are eliminated.
@@ -341,6 +347,8 @@ static int nf_ct_frag6_queue(struct nf_ct_frag6_queue *fq, struct sk_buff *skb,
341 347
342 /* Insert this fragment in the chain of fragments. */ 348 /* Insert this fragment in the chain of fragments. */
343 skb->next = next; 349 skb->next = next;
350 if (!next)
351 fq->q.fragments_tail = skb;
344 if (prev) 352 if (prev)
345 prev->next = skb; 353 prev->next = skb;
346 else 354 else
@@ -464,6 +472,7 @@ nf_ct_frag6_reasm(struct nf_ct_frag6_queue *fq, struct net_device *dev)
464 head->csum); 472 head->csum);
465 473
466 fq->q.fragments = NULL; 474 fq->q.fragments = NULL;
475 fq->q.fragments_tail = NULL;
467 476
468 /* all original skbs are linked into the NFCT_FRAG6_CB(head).orig */ 477 /* all original skbs are linked into the NFCT_FRAG6_CB(head).orig */
469 fp = skb_shinfo(head)->frag_list; 478 fp = skb_shinfo(head)->frag_list;