diff options
| -rw-r--r-- | net/rose/rose_loopback.c | 27 |
1 files changed, 16 insertions, 11 deletions
diff --git a/net/rose/rose_loopback.c b/net/rose/rose_loopback.c index 7af4f99c4a93..094a6621f8e8 100644 --- a/net/rose/rose_loopback.c +++ b/net/rose/rose_loopback.c | |||
| @@ -16,6 +16,7 @@ | |||
| 16 | #include <linux/init.h> | 16 | #include <linux/init.h> |
| 17 | 17 | ||
| 18 | static struct sk_buff_head loopback_queue; | 18 | static struct sk_buff_head loopback_queue; |
| 19 | #define ROSE_LOOPBACK_LIMIT 1000 | ||
| 19 | static struct timer_list loopback_timer; | 20 | static struct timer_list loopback_timer; |
| 20 | 21 | ||
| 21 | static void rose_set_loopback_timer(void); | 22 | static void rose_set_loopback_timer(void); |
| @@ -35,29 +36,27 @@ static int rose_loopback_running(void) | |||
| 35 | 36 | ||
| 36 | int rose_loopback_queue(struct sk_buff *skb, struct rose_neigh *neigh) | 37 | int rose_loopback_queue(struct sk_buff *skb, struct rose_neigh *neigh) |
| 37 | { | 38 | { |
| 38 | struct sk_buff *skbn; | 39 | struct sk_buff *skbn = NULL; |
| 39 | 40 | ||
| 40 | skbn = skb_clone(skb, GFP_ATOMIC); | 41 | if (skb_queue_len(&loopback_queue) < ROSE_LOOPBACK_LIMIT) |
| 42 | skbn = skb_clone(skb, GFP_ATOMIC); | ||
| 41 | 43 | ||
| 42 | kfree_skb(skb); | 44 | if (skbn) { |
| 43 | 45 | consume_skb(skb); | |
| 44 | if (skbn != NULL) { | ||
| 45 | skb_queue_tail(&loopback_queue, skbn); | 46 | skb_queue_tail(&loopback_queue, skbn); |
| 46 | 47 | ||
| 47 | if (!rose_loopback_running()) | 48 | if (!rose_loopback_running()) |
| 48 | rose_set_loopback_timer(); | 49 | rose_set_loopback_timer(); |
| 50 | } else { | ||
| 51 | kfree_skb(skb); | ||
| 49 | } | 52 | } |
| 50 | 53 | ||
| 51 | return 1; | 54 | return 1; |
| 52 | } | 55 | } |
| 53 | 56 | ||
| 54 | |||
| 55 | static void rose_set_loopback_timer(void) | 57 | static void rose_set_loopback_timer(void) |
| 56 | { | 58 | { |
| 57 | del_timer(&loopback_timer); | 59 | mod_timer(&loopback_timer, jiffies + 10); |
| 58 | |||
| 59 | loopback_timer.expires = jiffies + 10; | ||
| 60 | add_timer(&loopback_timer); | ||
| 61 | } | 60 | } |
| 62 | 61 | ||
| 63 | static void rose_loopback_timer(struct timer_list *unused) | 62 | static void rose_loopback_timer(struct timer_list *unused) |
| @@ -68,8 +67,12 @@ static void rose_loopback_timer(struct timer_list *unused) | |||
| 68 | struct sock *sk; | 67 | struct sock *sk; |
| 69 | unsigned short frametype; | 68 | unsigned short frametype; |
| 70 | unsigned int lci_i, lci_o; | 69 | unsigned int lci_i, lci_o; |
| 70 | int count; | ||
| 71 | 71 | ||
| 72 | while ((skb = skb_dequeue(&loopback_queue)) != NULL) { | 72 | for (count = 0; count < ROSE_LOOPBACK_LIMIT; count++) { |
| 73 | skb = skb_dequeue(&loopback_queue); | ||
| 74 | if (!skb) | ||
| 75 | return; | ||
| 73 | if (skb->len < ROSE_MIN_LEN) { | 76 | if (skb->len < ROSE_MIN_LEN) { |
| 74 | kfree_skb(skb); | 77 | kfree_skb(skb); |
| 75 | continue; | 78 | continue; |
| @@ -106,6 +109,8 @@ static void rose_loopback_timer(struct timer_list *unused) | |||
| 106 | kfree_skb(skb); | 109 | kfree_skb(skb); |
| 107 | } | 110 | } |
| 108 | } | 111 | } |
| 112 | if (!skb_queue_empty(&loopback_queue)) | ||
| 113 | mod_timer(&loopback_timer, jiffies + 1); | ||
| 109 | } | 114 | } |
| 110 | 115 | ||
| 111 | void __exit rose_loopback_clear(void) | 116 | void __exit rose_loopback_clear(void) |
