root/net/netrom/nr_loopback.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. nr_loopback_init
  2. nr_loopback_running
  3. nr_loopback_queue
  4. nr_loopback_timer
  5. nr_loopback_clear

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  *
   4  * Copyright Tomi Manninen OH2BNS (oh2bns@sral.fi)
   5  */
   6 #include <linux/types.h>
   7 #include <linux/slab.h>
   8 #include <linux/socket.h>
   9 #include <linux/timer.h>
  10 #include <net/ax25.h>
  11 #include <linux/skbuff.h>
  12 #include <net/netrom.h>
  13 #include <linux/init.h>
  14 
  15 static void nr_loopback_timer(struct timer_list *);
  16 
  17 static struct sk_buff_head loopback_queue;
  18 static DEFINE_TIMER(loopback_timer, nr_loopback_timer);
  19 
  20 void __init nr_loopback_init(void)
  21 {
  22         skb_queue_head_init(&loopback_queue);
  23 }
  24 
  25 static inline int nr_loopback_running(void)
  26 {
  27         return timer_pending(&loopback_timer);
  28 }
  29 
  30 int nr_loopback_queue(struct sk_buff *skb)
  31 {
  32         struct sk_buff *skbn;
  33 
  34         if ((skbn = alloc_skb(skb->len, GFP_ATOMIC)) != NULL) {
  35                 skb_copy_from_linear_data(skb, skb_put(skbn, skb->len), skb->len);
  36                 skb_reset_transport_header(skbn);
  37 
  38                 skb_queue_tail(&loopback_queue, skbn);
  39 
  40                 if (!nr_loopback_running())
  41                         mod_timer(&loopback_timer, jiffies + 10);
  42         }
  43 
  44         kfree_skb(skb);
  45         return 1;
  46 }
  47 
  48 static void nr_loopback_timer(struct timer_list *unused)
  49 {
  50         struct sk_buff *skb;
  51         ax25_address *nr_dest;
  52         struct net_device *dev;
  53 
  54         if ((skb = skb_dequeue(&loopback_queue)) != NULL) {
  55                 nr_dest = (ax25_address *)(skb->data + 7);
  56 
  57                 dev = nr_dev_get(nr_dest);
  58 
  59                 if (dev == NULL || nr_rx_frame(skb, dev) == 0)
  60                         kfree_skb(skb);
  61 
  62                 if (dev != NULL)
  63                         dev_put(dev);
  64 
  65                 if (!skb_queue_empty(&loopback_queue) && !nr_loopback_running())
  66                         mod_timer(&loopback_timer, jiffies + 10);
  67         }
  68 }
  69 
  70 void nr_loopback_clear(void)
  71 {
  72         del_timer_sync(&loopback_timer);
  73         skb_queue_purge(&loopback_queue);
  74 }

/* [<][>][^][v][top][bottom][index][help] */