[NETEM]: Support time based reordering
Change netem to support packets getting reordered because of variations in delay. Introduce a special case version of FIFO that queues packets in order based on the netem delay. Since netem is classful, those users that don't want jitter based reordering can just insert a pfifo instead of the default. This required changes to generic skbuff code to allow finer grain manipulation of sk_buff_head. Insertion into the middle and reverse walk. Signed-off-by: Stephen Hemminger <shemminger@osdl.org> Signed-off-by: Arnaldo Carvalho de Melo <acme@mandriva.com>
This commit is contained in:

committed by
Arnaldo Carvalho de Melo

parent
07aaa11540
commit
300ce174eb
@@ -602,6 +602,30 @@ static inline void skb_queue_head_init(struct sk_buff_head *list)
|
||||
* can only be called with interrupts disabled.
|
||||
*/
|
||||
|
||||
/**
|
||||
* __skb_queue_after - queue a buffer at the list head
|
||||
* @list: list to use
|
||||
* @prev: place after this buffer
|
||||
* @newsk: buffer to queue
|
||||
*
|
||||
* Queue a buffer int the middle of a list. This function takes no locks
|
||||
* and you must therefore hold required locks before calling it.
|
||||
*
|
||||
* A buffer cannot be placed on two lists at the same time.
|
||||
*/
|
||||
static inline void __skb_queue_after(struct sk_buff_head *list,
|
||||
struct sk_buff *prev,
|
||||
struct sk_buff *newsk)
|
||||
{
|
||||
struct sk_buff *next;
|
||||
list->qlen++;
|
||||
|
||||
next = prev->next;
|
||||
newsk->next = next;
|
||||
newsk->prev = prev;
|
||||
next->prev = prev->next = newsk;
|
||||
}
|
||||
|
||||
/**
|
||||
* __skb_queue_head - queue a buffer at the list head
|
||||
* @list: list to use
|
||||
@@ -616,14 +640,7 @@ extern void skb_queue_head(struct sk_buff_head *list, struct sk_buff *newsk);
|
||||
static inline void __skb_queue_head(struct sk_buff_head *list,
|
||||
struct sk_buff *newsk)
|
||||
{
|
||||
struct sk_buff *prev, *next;
|
||||
|
||||
list->qlen++;
|
||||
prev = (struct sk_buff *)list;
|
||||
next = prev->next;
|
||||
newsk->next = next;
|
||||
newsk->prev = prev;
|
||||
next->prev = prev->next = newsk;
|
||||
__skb_queue_after(list, (struct sk_buff *)list, newsk);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1203,6 +1220,11 @@ static inline void kunmap_skb_frag(void *vaddr)
|
||||
prefetch(skb->next), (skb != (struct sk_buff *)(queue)); \
|
||||
skb = skb->next)
|
||||
|
||||
#define skb_queue_reverse_walk(queue, skb) \
|
||||
for (skb = (queue)->prev; \
|
||||
prefetch(skb->prev), (skb != (struct sk_buff *)(queue)); \
|
||||
skb = skb->prev)
|
||||
|
||||
|
||||
extern struct sk_buff *skb_recv_datagram(struct sock *sk, unsigned flags,
|
||||
int noblock, int *err);
|
||||
|
Reference in New Issue
Block a user