root/net/ax25/ax25_ds_timer.c

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

DEFINITIONS

This source file includes following definitions.
  1. ax25_ds_setup_timer
  2. ax25_ds_del_timer
  3. ax25_ds_set_timer
  4. ax25_ds_timeout
  5. ax25_ds_heartbeat_expiry
  6. ax25_ds_t3timer_expiry
  7. ax25_ds_idletimer_expiry
  8. ax25_ds_t1_timeout

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  *
   4  * Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
   5  * Copyright (C) Joerg Reuter DL1BKE (jreuter@yaina.de)
   6  */
   7 #include <linux/errno.h>
   8 #include <linux/types.h>
   9 #include <linux/socket.h>
  10 #include <linux/spinlock.h>
  11 #include <linux/in.h>
  12 #include <linux/kernel.h>
  13 #include <linux/jiffies.h>
  14 #include <linux/timer.h>
  15 #include <linux/string.h>
  16 #include <linux/sockios.h>
  17 #include <linux/net.h>
  18 #include <net/tcp_states.h>
  19 #include <net/ax25.h>
  20 #include <linux/inet.h>
  21 #include <linux/netdevice.h>
  22 #include <linux/skbuff.h>
  23 #include <net/sock.h>
  24 #include <linux/uaccess.h>
  25 #include <linux/fcntl.h>
  26 #include <linux/mm.h>
  27 #include <linux/interrupt.h>
  28 
  29 static void ax25_ds_timeout(struct timer_list *);
  30 
  31 /*
  32  *      Add DAMA slave timeout timer to timer list.
  33  *      Unlike the connection based timers the timeout function gets
  34  *      triggered every second. Please note that NET_AX25_DAMA_SLAVE_TIMEOUT
  35  *      (aka /proc/sys/net/ax25/{dev}/dama_slave_timeout) is still in
  36  *      1/10th of a second.
  37  */
  38 
  39 void ax25_ds_setup_timer(ax25_dev *ax25_dev)
  40 {
  41         timer_setup(&ax25_dev->dama.slave_timer, ax25_ds_timeout, 0);
  42 }
  43 
  44 void ax25_ds_del_timer(ax25_dev *ax25_dev)
  45 {
  46         if (ax25_dev)
  47                 del_timer(&ax25_dev->dama.slave_timer);
  48 }
  49 
  50 void ax25_ds_set_timer(ax25_dev *ax25_dev)
  51 {
  52         if (ax25_dev == NULL)           /* paranoia */
  53                 return;
  54 
  55         ax25_dev->dama.slave_timeout =
  56                 msecs_to_jiffies(ax25_dev->values[AX25_VALUES_DS_TIMEOUT]) / 10;
  57         mod_timer(&ax25_dev->dama.slave_timer, jiffies + HZ);
  58 }
  59 
  60 /*
  61  *      DAMA Slave Timeout
  62  *      Silently discard all (slave) connections in case our master forgot us...
  63  */
  64 
  65 static void ax25_ds_timeout(struct timer_list *t)
  66 {
  67         ax25_dev *ax25_dev = from_timer(ax25_dev, t, dama.slave_timer);
  68         ax25_cb *ax25;
  69 
  70         if (ax25_dev == NULL || !ax25_dev->dama.slave)
  71                 return;                 /* Yikes! */
  72 
  73         if (!ax25_dev->dama.slave_timeout || --ax25_dev->dama.slave_timeout) {
  74                 ax25_ds_set_timer(ax25_dev);
  75                 return;
  76         }
  77 
  78         spin_lock(&ax25_list_lock);
  79         ax25_for_each(ax25, &ax25_list) {
  80                 if (ax25->ax25_dev != ax25_dev || !(ax25->condition & AX25_COND_DAMA_MODE))
  81                         continue;
  82 
  83                 ax25_send_control(ax25, AX25_DISC, AX25_POLLON, AX25_COMMAND);
  84                 ax25_disconnect(ax25, ETIMEDOUT);
  85         }
  86         spin_unlock(&ax25_list_lock);
  87 
  88         ax25_dev_dama_off(ax25_dev);
  89 }
  90 
  91 void ax25_ds_heartbeat_expiry(ax25_cb *ax25)
  92 {
  93         struct sock *sk=ax25->sk;
  94 
  95         if (sk)
  96                 bh_lock_sock(sk);
  97 
  98         switch (ax25->state) {
  99 
 100         case AX25_STATE_0:
 101         case AX25_STATE_2:
 102                 /* Magic here: If we listen() and a new link dies before it
 103                    is accepted() it isn't 'dead' so doesn't get removed. */
 104                 if (!sk || sock_flag(sk, SOCK_DESTROY) ||
 105                     (sk->sk_state == TCP_LISTEN &&
 106                      sock_flag(sk, SOCK_DEAD))) {
 107                         if (sk) {
 108                                 sock_hold(sk);
 109                                 ax25_destroy_socket(ax25);
 110                                 bh_unlock_sock(sk);
 111                                 /* Ungrab socket and destroy it */
 112                                 sock_put(sk);
 113                         } else
 114                                 ax25_destroy_socket(ax25);
 115                         return;
 116                 }
 117                 break;
 118 
 119         case AX25_STATE_3:
 120                 /*
 121                  * Check the state of the receive buffer.
 122                  */
 123                 if (sk != NULL) {
 124                         if (atomic_read(&sk->sk_rmem_alloc) <
 125                             (sk->sk_rcvbuf >> 1) &&
 126                             (ax25->condition & AX25_COND_OWN_RX_BUSY)) {
 127                                 ax25->condition &= ~AX25_COND_OWN_RX_BUSY;
 128                                 ax25->condition &= ~AX25_COND_ACK_PENDING;
 129                                 break;
 130                         }
 131                 }
 132                 break;
 133         }
 134 
 135         if (sk)
 136                 bh_unlock_sock(sk);
 137 
 138         ax25_start_heartbeat(ax25);
 139 }
 140 
 141 /* dl1bke 960114: T3 works much like the IDLE timeout, but
 142  *                gets reloaded with every frame for this
 143  *                connection.
 144  */
 145 void ax25_ds_t3timer_expiry(ax25_cb *ax25)
 146 {
 147         ax25_send_control(ax25, AX25_DISC, AX25_POLLON, AX25_COMMAND);
 148         ax25_dama_off(ax25);
 149         ax25_disconnect(ax25, ETIMEDOUT);
 150 }
 151 
 152 /* dl1bke 960228: close the connection when IDLE expires.
 153  *                unlike T3 this timer gets reloaded only on
 154  *                I frames.
 155  */
 156 void ax25_ds_idletimer_expiry(ax25_cb *ax25)
 157 {
 158         ax25_clear_queues(ax25);
 159 
 160         ax25->n2count = 0;
 161         ax25->state = AX25_STATE_2;
 162 
 163         ax25_calculate_t1(ax25);
 164         ax25_start_t1timer(ax25);
 165         ax25_stop_t3timer(ax25);
 166 
 167         if (ax25->sk != NULL) {
 168                 bh_lock_sock(ax25->sk);
 169                 ax25->sk->sk_state     = TCP_CLOSE;
 170                 ax25->sk->sk_err       = 0;
 171                 ax25->sk->sk_shutdown |= SEND_SHUTDOWN;
 172                 if (!sock_flag(ax25->sk, SOCK_DEAD)) {
 173                         ax25->sk->sk_state_change(ax25->sk);
 174                         sock_set_flag(ax25->sk, SOCK_DEAD);
 175                 }
 176                 bh_unlock_sock(ax25->sk);
 177         }
 178 }
 179 
 180 /* dl1bke 960114: The DAMA protocol requires to send data and SABM/DISC
 181  *                within the poll of any connected channel. Remember
 182  *                that we are not allowed to send anything unless we
 183  *                get polled by the Master.
 184  *
 185  *                Thus we'll have to do parts of our T1 handling in
 186  *                ax25_enquiry_response().
 187  */
 188 void ax25_ds_t1_timeout(ax25_cb *ax25)
 189 {
 190         switch (ax25->state) {
 191         case AX25_STATE_1:
 192                 if (ax25->n2count == ax25->n2) {
 193                         if (ax25->modulus == AX25_MODULUS) {
 194                                 ax25_disconnect(ax25, ETIMEDOUT);
 195                                 return;
 196                         } else {
 197                                 ax25->modulus = AX25_MODULUS;
 198                                 ax25->window  = ax25->ax25_dev->values[AX25_VALUES_WINDOW];
 199                                 ax25->n2count = 0;
 200                                 ax25_send_control(ax25, AX25_SABM, AX25_POLLOFF, AX25_COMMAND);
 201                         }
 202                 } else {
 203                         ax25->n2count++;
 204                         if (ax25->modulus == AX25_MODULUS)
 205                                 ax25_send_control(ax25, AX25_SABM, AX25_POLLOFF, AX25_COMMAND);
 206                         else
 207                                 ax25_send_control(ax25, AX25_SABME, AX25_POLLOFF, AX25_COMMAND);
 208                 }
 209                 break;
 210 
 211         case AX25_STATE_2:
 212                 if (ax25->n2count == ax25->n2) {
 213                         ax25_send_control(ax25, AX25_DISC, AX25_POLLON, AX25_COMMAND);
 214                         if (!sock_flag(ax25->sk, SOCK_DESTROY))
 215                                 ax25_disconnect(ax25, ETIMEDOUT);
 216                         return;
 217                 } else {
 218                         ax25->n2count++;
 219                 }
 220                 break;
 221 
 222         case AX25_STATE_3:
 223                 if (ax25->n2count == ax25->n2) {
 224                         ax25_send_control(ax25, AX25_DM, AX25_POLLON, AX25_RESPONSE);
 225                         ax25_disconnect(ax25, ETIMEDOUT);
 226                         return;
 227                 } else {
 228                         ax25->n2count++;
 229                 }
 230                 break;
 231         }
 232 
 233         ax25_calculate_t1(ax25);
 234         ax25_start_t1timer(ax25);
 235 }

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