ip: add helpers to process in-order fragments faster.
This patch introduces several helper functions/macros that will be used in the follow-up patch. No runtime changes yet. The new logic (fully implemented in the second patch) is as follows: * Nodes in the rb-tree will now contain not single fragments, but lists of consecutive fragments ("runs"). * At each point in time, the current "active" run at the tail is maintained/tracked. Fragments that arrive in-order, adjacent to the previous tail fragment, are added to this tail run without triggering the re-balancing of the rb-tree. * If a fragment arrives out of order with the offset _before_ the tail run, it is inserted into the rb-tree as a single fragment. * If a fragment arrives after the current tail fragment (with a gap), it starts a new "tail" run, as is inserted into the rb-tree at the end as the head of the new run. skb->cb is used to store additional information needed here (suggested by Eric Dumazet). Reported-by: Willem de Bruijn <willemb@google.com> Signed-off-by: Peter Oskolkov <posk@google.com> Cc: Eric Dumazet <edumazet@google.com> Cc: Florian Westphal <fw@strlen.de> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:

committato da
David S. Miller

parent
6a92ef08a1
commit
353c9cb360
@@ -57,7 +57,9 @@ struct frag_v6_compare_key {
|
||||
* @lock: spinlock protecting this frag
|
||||
* @refcnt: reference count of the queue
|
||||
* @fragments: received fragments head
|
||||
* @rb_fragments: received fragments rb-tree root
|
||||
* @fragments_tail: received fragments tail
|
||||
* @last_run_head: the head of the last "run". see ip_fragment.c
|
||||
* @stamp: timestamp of the last received fragment
|
||||
* @len: total length of the original datagram
|
||||
* @meat: length of received fragments so far
|
||||
@@ -78,6 +80,7 @@ struct inet_frag_queue {
|
||||
struct sk_buff *fragments; /* Used in IPv6. */
|
||||
struct rb_root rb_fragments; /* Used in IPv4. */
|
||||
struct sk_buff *fragments_tail;
|
||||
struct sk_buff *last_run_head;
|
||||
ktime_t stamp;
|
||||
int len;
|
||||
int meat;
|
||||
@@ -113,6 +116,9 @@ void inet_frag_kill(struct inet_frag_queue *q);
|
||||
void inet_frag_destroy(struct inet_frag_queue *q);
|
||||
struct inet_frag_queue *inet_frag_find(struct netns_frags *nf, void *key);
|
||||
|
||||
/* Free all skbs in the queue; return the sum of their truesizes. */
|
||||
unsigned int inet_frag_rbtree_purge(struct rb_root *root);
|
||||
|
||||
static inline void inet_frag_put(struct inet_frag_queue *q)
|
||||
{
|
||||
if (refcount_dec_and_test(&q->refcnt))
|
||||
|
Fai riferimento in un nuovo problema
Block a user