ax25_iface.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. *
  4. * Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
  5. */
  6. #include <linux/errno.h>
  7. #include <linux/types.h>
  8. #include <linux/socket.h>
  9. #include <linux/in.h>
  10. #include <linux/kernel.h>
  11. #include <linux/module.h>
  12. #include <linux/spinlock.h>
  13. #include <linux/timer.h>
  14. #include <linux/string.h>
  15. #include <linux/sockios.h>
  16. #include <linux/net.h>
  17. #include <linux/slab.h>
  18. #include <net/ax25.h>
  19. #include <linux/inet.h>
  20. #include <linux/netdevice.h>
  21. #include <linux/skbuff.h>
  22. #include <net/sock.h>
  23. #include <linux/uaccess.h>
  24. #include <linux/fcntl.h>
  25. #include <linux/mm.h>
  26. #include <linux/interrupt.h>
  27. static struct ax25_protocol *protocol_list;
  28. static DEFINE_RWLOCK(protocol_list_lock);
  29. static HLIST_HEAD(ax25_linkfail_list);
  30. static DEFINE_SPINLOCK(linkfail_lock);
  31. static struct listen_struct {
  32. struct listen_struct *next;
  33. ax25_address callsign;
  34. struct net_device *dev;
  35. } *listen_list = NULL;
  36. static DEFINE_SPINLOCK(listen_lock);
  37. /*
  38. * Do not register the internal protocols AX25_P_TEXT, AX25_P_SEGMENT,
  39. * AX25_P_IP or AX25_P_ARP ...
  40. */
  41. void ax25_register_pid(struct ax25_protocol *ap)
  42. {
  43. write_lock_bh(&protocol_list_lock);
  44. ap->next = protocol_list;
  45. protocol_list = ap;
  46. write_unlock_bh(&protocol_list_lock);
  47. }
  48. EXPORT_SYMBOL_GPL(ax25_register_pid);
  49. void ax25_protocol_release(unsigned int pid)
  50. {
  51. struct ax25_protocol *protocol;
  52. write_lock_bh(&protocol_list_lock);
  53. protocol = protocol_list;
  54. if (protocol == NULL)
  55. goto out;
  56. if (protocol->pid == pid) {
  57. protocol_list = protocol->next;
  58. goto out;
  59. }
  60. while (protocol != NULL && protocol->next != NULL) {
  61. if (protocol->next->pid == pid) {
  62. protocol->next = protocol->next->next;
  63. goto out;
  64. }
  65. protocol = protocol->next;
  66. }
  67. out:
  68. write_unlock_bh(&protocol_list_lock);
  69. }
  70. EXPORT_SYMBOL(ax25_protocol_release);
  71. void ax25_linkfail_register(struct ax25_linkfail *lf)
  72. {
  73. spin_lock_bh(&linkfail_lock);
  74. hlist_add_head(&lf->lf_node, &ax25_linkfail_list);
  75. spin_unlock_bh(&linkfail_lock);
  76. }
  77. EXPORT_SYMBOL(ax25_linkfail_register);
  78. void ax25_linkfail_release(struct ax25_linkfail *lf)
  79. {
  80. spin_lock_bh(&linkfail_lock);
  81. hlist_del_init(&lf->lf_node);
  82. spin_unlock_bh(&linkfail_lock);
  83. }
  84. EXPORT_SYMBOL(ax25_linkfail_release);
  85. int ax25_listen_register(ax25_address *callsign, struct net_device *dev)
  86. {
  87. struct listen_struct *listen;
  88. if (ax25_listen_mine(callsign, dev))
  89. return 0;
  90. if ((listen = kmalloc(sizeof(*listen), GFP_ATOMIC)) == NULL)
  91. return -ENOMEM;
  92. listen->callsign = *callsign;
  93. listen->dev = dev;
  94. spin_lock_bh(&listen_lock);
  95. listen->next = listen_list;
  96. listen_list = listen;
  97. spin_unlock_bh(&listen_lock);
  98. return 0;
  99. }
  100. EXPORT_SYMBOL(ax25_listen_register);
  101. void ax25_listen_release(ax25_address *callsign, struct net_device *dev)
  102. {
  103. struct listen_struct *s, *listen;
  104. spin_lock_bh(&listen_lock);
  105. listen = listen_list;
  106. if (listen == NULL) {
  107. spin_unlock_bh(&listen_lock);
  108. return;
  109. }
  110. if (ax25cmp(&listen->callsign, callsign) == 0 && listen->dev == dev) {
  111. listen_list = listen->next;
  112. spin_unlock_bh(&listen_lock);
  113. kfree(listen);
  114. return;
  115. }
  116. while (listen != NULL && listen->next != NULL) {
  117. if (ax25cmp(&listen->next->callsign, callsign) == 0 && listen->next->dev == dev) {
  118. s = listen->next;
  119. listen->next = listen->next->next;
  120. spin_unlock_bh(&listen_lock);
  121. kfree(s);
  122. return;
  123. }
  124. listen = listen->next;
  125. }
  126. spin_unlock_bh(&listen_lock);
  127. }
  128. EXPORT_SYMBOL(ax25_listen_release);
  129. int (*ax25_protocol_function(unsigned int pid))(struct sk_buff *, ax25_cb *)
  130. {
  131. int (*res)(struct sk_buff *, ax25_cb *) = NULL;
  132. struct ax25_protocol *protocol;
  133. read_lock(&protocol_list_lock);
  134. for (protocol = protocol_list; protocol != NULL; protocol = protocol->next)
  135. if (protocol->pid == pid) {
  136. res = protocol->func;
  137. break;
  138. }
  139. read_unlock(&protocol_list_lock);
  140. return res;
  141. }
  142. int ax25_listen_mine(ax25_address *callsign, struct net_device *dev)
  143. {
  144. struct listen_struct *listen;
  145. spin_lock_bh(&listen_lock);
  146. for (listen = listen_list; listen != NULL; listen = listen->next)
  147. if (ax25cmp(&listen->callsign, callsign) == 0 &&
  148. (listen->dev == dev || listen->dev == NULL)) {
  149. spin_unlock_bh(&listen_lock);
  150. return 1;
  151. }
  152. spin_unlock_bh(&listen_lock);
  153. return 0;
  154. }
  155. void ax25_link_failed(ax25_cb *ax25, int reason)
  156. {
  157. struct ax25_linkfail *lf;
  158. spin_lock_bh(&linkfail_lock);
  159. hlist_for_each_entry(lf, &ax25_linkfail_list, lf_node)
  160. lf->func(ax25, reason);
  161. spin_unlock_bh(&linkfail_lock);
  162. }
  163. int ax25_protocol_is_registered(unsigned int pid)
  164. {
  165. struct ax25_protocol *protocol;
  166. int res = 0;
  167. read_lock_bh(&protocol_list_lock);
  168. for (protocol = protocol_list; protocol != NULL; protocol = protocol->next)
  169. if (protocol->pid == pid) {
  170. res = 1;
  171. break;
  172. }
  173. read_unlock_bh(&protocol_list_lock);
  174. return res;
  175. }