~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/net/netrom/nr_loopback.c

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  *      NET/ROM release 007
  3  *
  4  *      This code REQUIRES 2.1.15 or higher/ NET3.038
  5  *
  6  *      This module:
  7  *              This module is free software; you can redistribute it and/or
  8  *              modify it under the terms of the GNU General Public License
  9  *              as published by the Free Software Foundation; either version
 10  *              2 of the License, or (at your option) any later version.
 11  *
 12  *      History
 13  *      NET/ROM 007     Tomi(OH2BNS)    Created this file.
 14  *                                      Small change in nr_loopback_queue().
 15  *
 16  */
 17 
 18 #include <linux/types.h>
 19 #include <linux/socket.h>
 20 #include <linux/timer.h>
 21 #include <net/ax25.h>
 22 #include <linux/skbuff.h>
 23 #include <net/netrom.h>
 24 #include <linux/init.h>
 25 
 26 static struct sk_buff_head loopback_queue;
 27 static struct timer_list loopback_timer;
 28 
 29 static void nr_set_loopback_timer(void);
 30 
 31 void nr_loopback_init(void)
 32 {
 33         skb_queue_head_init(&loopback_queue);
 34 
 35         init_timer(&loopback_timer);
 36 }
 37 
 38 static int nr_loopback_running(void)
 39 {
 40         return timer_pending(&loopback_timer);
 41 }
 42 
 43 int nr_loopback_queue(struct sk_buff *skb)
 44 {
 45         struct sk_buff *skbn;
 46 
 47         if ((skbn = alloc_skb(skb->len, GFP_ATOMIC)) != NULL) {
 48                 memcpy(skb_put(skbn, skb->len), skb->data, skb->len);
 49                 skbn->h.raw = skbn->data;
 50 
 51                 skb_queue_tail(&loopback_queue, skbn);
 52 
 53                 if (!nr_loopback_running())
 54                         nr_set_loopback_timer();
 55         }
 56 
 57         kfree_skb(skb);
 58         return 1;
 59 }
 60 
 61 static void nr_loopback_timer(unsigned long);
 62 
 63 static void nr_set_loopback_timer(void)
 64 {
 65         del_timer(&loopback_timer);
 66 
 67         loopback_timer.data     = 0;
 68         loopback_timer.function = &nr_loopback_timer;
 69         loopback_timer.expires  = jiffies + 10;
 70 
 71         add_timer(&loopback_timer);
 72 }
 73 
 74 static void nr_loopback_timer(unsigned long param)
 75 {
 76         struct sk_buff *skb;
 77         ax25_address *nr_dest;
 78         struct net_device *dev;
 79 
 80         if ((skb = skb_dequeue(&loopback_queue)) != NULL) {
 81                 nr_dest = (ax25_address *)(skb->data + 7);
 82 
 83                 dev = nr_dev_get(nr_dest);
 84 
 85                 if (dev == NULL || nr_rx_frame(skb, dev) == 0)
 86                         kfree_skb(skb);
 87 
 88                 if (!skb_queue_empty(&loopback_queue) && !nr_loopback_running())
 89                         nr_set_loopback_timer();
 90         }
 91 }
 92 
 93 void __exit nr_loopback_clear(void)
 94 {
 95         struct sk_buff *skb;
 96 
 97         del_timer(&loopback_timer);
 98 
 99         while ((skb = skb_dequeue(&loopback_queue)) != NULL)
100                 kfree_skb(skb);
101 }
102 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.