signaling.c 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. /* net/atm/signaling.c - ATM signaling */
  2. /* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */
  3. #define pr_fmt(fmt) KBUILD_MODNAME ":%s: " fmt, __func__
  4. #include <linux/errno.h> /* error codes */
  5. #include <linux/kernel.h> /* printk */
  6. #include <linux/skbuff.h>
  7. #include <linux/wait.h>
  8. #include <linux/sched.h> /* jiffies and HZ */
  9. #include <linux/atm.h> /* ATM stuff */
  10. #include <linux/atmsap.h>
  11. #include <linux/atmsvc.h>
  12. #include <linux/atmdev.h>
  13. #include <linux/bitops.h>
  14. #include <linux/slab.h>
  15. #include "resources.h"
  16. #include "signaling.h"
  17. #undef WAIT_FOR_DEMON /* #define this if system calls on SVC sockets
  18. should block until the demon runs.
  19. Danger: may cause nasty hangs if the demon
  20. crashes. */
  21. struct atm_vcc *sigd = NULL;
  22. #ifdef WAIT_FOR_DEMON
  23. static DECLARE_WAIT_QUEUE_HEAD(sigd_sleep);
  24. #endif
  25. static void sigd_put_skb(struct sk_buff *skb)
  26. {
  27. #ifdef WAIT_FOR_DEMON
  28. DECLARE_WAITQUEUE(wait, current);
  29. add_wait_queue(&sigd_sleep, &wait);
  30. while (!sigd) {
  31. set_current_state(TASK_UNINTERRUPTIBLE);
  32. pr_debug("atmsvc: waiting for signaling daemon...\n");
  33. schedule();
  34. }
  35. current->state = TASK_RUNNING;
  36. remove_wait_queue(&sigd_sleep, &wait);
  37. #else
  38. if (!sigd) {
  39. pr_debug("atmsvc: no signaling daemon\n");
  40. kfree_skb(skb);
  41. return;
  42. }
  43. #endif
  44. atm_force_charge(sigd, skb->truesize);
  45. skb_queue_tail(&sk_atm(sigd)->sk_receive_queue, skb);
  46. sk_atm(sigd)->sk_data_ready(sk_atm(sigd), skb->len);
  47. }
  48. static void modify_qos(struct atm_vcc *vcc, struct atmsvc_msg *msg)
  49. {
  50. struct sk_buff *skb;
  51. if (test_bit(ATM_VF_RELEASED, &vcc->flags) ||
  52. !test_bit(ATM_VF_READY, &vcc->flags))
  53. return;
  54. msg->type = as_error;
  55. if (!vcc->dev->ops->change_qos)
  56. msg->reply = -EOPNOTSUPP;
  57. else {
  58. /* should lock VCC */
  59. msg->reply = vcc->dev->ops->change_qos(vcc, &msg->qos,
  60. msg->reply);
  61. if (!msg->reply)
  62. msg->type = as_okay;
  63. }
  64. /*
  65. * Should probably just turn around the old skb. But the, the buffer
  66. * space accounting needs to follow the change too. Maybe later.
  67. */
  68. while (!(skb = alloc_skb(sizeof(struct atmsvc_msg), GFP_KERNEL)))
  69. schedule();
  70. *(struct atmsvc_msg *)skb_put(skb, sizeof(struct atmsvc_msg)) = *msg;
  71. sigd_put_skb(skb);
  72. }
  73. static int sigd_send(struct atm_vcc *vcc, struct sk_buff *skb)
  74. {
  75. struct atmsvc_msg *msg;
  76. struct atm_vcc *session_vcc;
  77. struct sock *sk;
  78. msg = (struct atmsvc_msg *) skb->data;
  79. atomic_sub(skb->truesize, &sk_atm(vcc)->sk_wmem_alloc);
  80. vcc = *(struct atm_vcc **) &msg->vcc;
  81. pr_debug("%d (0x%lx)\n", (int)msg->type, (unsigned long)vcc);
  82. sk = sk_atm(vcc);
  83. switch (msg->type) {
  84. case as_okay:
  85. sk->sk_err = -msg->reply;
  86. clear_bit(ATM_VF_WAITING, &vcc->flags);
  87. if (!*vcc->local.sas_addr.prv && !*vcc->local.sas_addr.pub) {
  88. vcc->local.sas_family = AF_ATMSVC;
  89. memcpy(vcc->local.sas_addr.prv,
  90. msg->local.sas_addr.prv, ATM_ESA_LEN);
  91. memcpy(vcc->local.sas_addr.pub,
  92. msg->local.sas_addr.pub, ATM_E164_LEN + 1);
  93. }
  94. session_vcc = vcc->session ? vcc->session : vcc;
  95. if (session_vcc->vpi || session_vcc->vci)
  96. break;
  97. session_vcc->itf = msg->pvc.sap_addr.itf;
  98. session_vcc->vpi = msg->pvc.sap_addr.vpi;
  99. session_vcc->vci = msg->pvc.sap_addr.vci;
  100. if (session_vcc->vpi || session_vcc->vci)
  101. session_vcc->qos = msg->qos;
  102. break;
  103. case as_error:
  104. clear_bit(ATM_VF_REGIS, &vcc->flags);
  105. clear_bit(ATM_VF_READY, &vcc->flags);
  106. sk->sk_err = -msg->reply;
  107. clear_bit(ATM_VF_WAITING, &vcc->flags);
  108. break;
  109. case as_indicate:
  110. vcc = *(struct atm_vcc **)&msg->listen_vcc;
  111. sk = sk_atm(vcc);
  112. pr_debug("as_indicate!!!\n");
  113. lock_sock(sk);
  114. if (sk_acceptq_is_full(sk)) {
  115. sigd_enq(NULL, as_reject, vcc, NULL, NULL);
  116. dev_kfree_skb(skb);
  117. goto as_indicate_complete;
  118. }
  119. sk->sk_ack_backlog++;
  120. skb_queue_tail(&sk->sk_receive_queue, skb);
  121. pr_debug("waking sk_sleep(sk) 0x%p\n", sk_sleep(sk));
  122. sk->sk_state_change(sk);
  123. as_indicate_complete:
  124. release_sock(sk);
  125. return 0;
  126. case as_close:
  127. set_bit(ATM_VF_RELEASED, &vcc->flags);
  128. vcc_release_async(vcc, msg->reply);
  129. goto out;
  130. case as_modify:
  131. modify_qos(vcc, msg);
  132. break;
  133. case as_addparty:
  134. case as_dropparty:
  135. sk->sk_err_soft = msg->reply;
  136. /* < 0 failure, otherwise ep_ref */
  137. clear_bit(ATM_VF_WAITING, &vcc->flags);
  138. break;
  139. default:
  140. pr_alert("bad message type %d\n", (int)msg->type);
  141. return -EINVAL;
  142. }
  143. sk->sk_state_change(sk);
  144. out:
  145. dev_kfree_skb(skb);
  146. return 0;
  147. }
  148. void sigd_enq2(struct atm_vcc *vcc, enum atmsvc_msg_type type,
  149. struct atm_vcc *listen_vcc, const struct sockaddr_atmpvc *pvc,
  150. const struct sockaddr_atmsvc *svc, const struct atm_qos *qos,
  151. int reply)
  152. {
  153. struct sk_buff *skb;
  154. struct atmsvc_msg *msg;
  155. static unsigned int session = 0;
  156. pr_debug("%d (0x%p)\n", (int)type, vcc);
  157. while (!(skb = alloc_skb(sizeof(struct atmsvc_msg), GFP_KERNEL)))
  158. schedule();
  159. msg = (struct atmsvc_msg *)skb_put(skb, sizeof(struct atmsvc_msg));
  160. memset(msg, 0, sizeof(*msg));
  161. msg->type = type;
  162. *(struct atm_vcc **) &msg->vcc = vcc;
  163. *(struct atm_vcc **) &msg->listen_vcc = listen_vcc;
  164. msg->reply = reply;
  165. if (qos)
  166. msg->qos = *qos;
  167. if (vcc)
  168. msg->sap = vcc->sap;
  169. if (svc)
  170. msg->svc = *svc;
  171. if (vcc)
  172. msg->local = vcc->local;
  173. if (pvc)
  174. msg->pvc = *pvc;
  175. if (vcc) {
  176. if (type == as_connect && test_bit(ATM_VF_SESSION, &vcc->flags))
  177. msg->session = ++session;
  178. /* every new pmp connect gets the next session number */
  179. }
  180. sigd_put_skb(skb);
  181. if (vcc)
  182. set_bit(ATM_VF_REGIS, &vcc->flags);
  183. }
  184. void sigd_enq(struct atm_vcc *vcc, enum atmsvc_msg_type type,
  185. struct atm_vcc *listen_vcc, const struct sockaddr_atmpvc *pvc,
  186. const struct sockaddr_atmsvc *svc)
  187. {
  188. sigd_enq2(vcc, type, listen_vcc, pvc, svc, vcc ? &vcc->qos : NULL, 0);
  189. /* other ISP applications may use "reply" */
  190. }
  191. static void purge_vcc(struct atm_vcc *vcc)
  192. {
  193. if (sk_atm(vcc)->sk_family == PF_ATMSVC &&
  194. !test_bit(ATM_VF_META, &vcc->flags)) {
  195. set_bit(ATM_VF_RELEASED, &vcc->flags);
  196. clear_bit(ATM_VF_REGIS, &vcc->flags);
  197. vcc_release_async(vcc, -EUNATCH);
  198. }
  199. }
  200. static void sigd_close(struct atm_vcc *vcc)
  201. {
  202. struct hlist_node *node;
  203. struct sock *s;
  204. int i;
  205. pr_debug("\n");
  206. sigd = NULL;
  207. if (skb_peek(&sk_atm(vcc)->sk_receive_queue))
  208. pr_err("closing with requests pending\n");
  209. skb_queue_purge(&sk_atm(vcc)->sk_receive_queue);
  210. read_lock(&vcc_sklist_lock);
  211. for (i = 0; i < VCC_HTABLE_SIZE; ++i) {
  212. struct hlist_head *head = &vcc_hash[i];
  213. sk_for_each(s, node, head) {
  214. vcc = atm_sk(s);
  215. purge_vcc(vcc);
  216. }
  217. }
  218. read_unlock(&vcc_sklist_lock);
  219. }
  220. static struct atmdev_ops sigd_dev_ops = {
  221. .close = sigd_close,
  222. .send = sigd_send
  223. };
  224. static struct atm_dev sigd_dev = {
  225. .ops = &sigd_dev_ops,
  226. .type = "sig",
  227. .number = 999,
  228. .lock = __SPIN_LOCK_UNLOCKED(sigd_dev.lock)
  229. };
  230. int sigd_attach(struct atm_vcc *vcc)
  231. {
  232. if (sigd)
  233. return -EADDRINUSE;
  234. pr_debug("\n");
  235. sigd = vcc;
  236. vcc->dev = &sigd_dev;
  237. vcc_insert_socket(sk_atm(vcc));
  238. set_bit(ATM_VF_META, &vcc->flags);
  239. set_bit(ATM_VF_READY, &vcc->flags);
  240. #ifdef WAIT_FOR_DEMON
  241. wake_up(&sigd_sleep);
  242. #endif
  243. return 0;
  244. }