llc_if.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. /*
  2. * llc_if.c - Defines LLC interface to upper layer
  3. *
  4. * Copyright (c) 1997 by Procom Technology, Inc.
  5. * 2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
  6. *
  7. * This program can be redistributed or modified under the terms of the
  8. * GNU General Public License as published by the Free Software Foundation.
  9. * This program is distributed without any warranty or implied warranty
  10. * of merchantability or fitness for a particular purpose.
  11. *
  12. * See the GNU General Public License for more details.
  13. */
  14. #include <linux/module.h>
  15. #include <linux/kernel.h>
  16. #include <linux/netdevice.h>
  17. #include <asm/errno.h>
  18. #include <net/llc_if.h>
  19. #include <net/llc_sap.h>
  20. #include <net/llc_s_ev.h>
  21. #include <net/llc_conn.h>
  22. #include <net/sock.h>
  23. #include <net/llc_c_ev.h>
  24. #include <net/llc_c_ac.h>
  25. #include <net/llc_c_st.h>
  26. #include <net/tcp_states.h>
  27. /**
  28. * llc_build_and_send_pkt - Connection data sending for upper layers.
  29. * @sk: connection
  30. * @skb: packet to send
  31. *
  32. * This function is called when upper layer wants to send data using
  33. * connection oriented communication mode. During sending data, connection
  34. * will be locked and received frames and expired timers will be queued.
  35. * Returns 0 for success, -ECONNABORTED when the connection already
  36. * closed and -EBUSY when sending data is not permitted in this state or
  37. * LLC has send an I pdu with p bit set to 1 and is waiting for it's
  38. * response.
  39. */
  40. int llc_build_and_send_pkt(struct sock *sk, struct sk_buff *skb)
  41. {
  42. struct llc_conn_state_ev *ev;
  43. int rc = -ECONNABORTED;
  44. struct llc_sock *llc = llc_sk(sk);
  45. if (unlikely(llc->state == LLC_CONN_STATE_ADM))
  46. goto out;
  47. rc = -EBUSY;
  48. if (unlikely(llc_data_accept_state(llc->state) || /* data_conn_refuse */
  49. llc->p_flag)) {
  50. llc->failed_data_req = 1;
  51. goto out;
  52. }
  53. ev = llc_conn_ev(skb);
  54. ev->type = LLC_CONN_EV_TYPE_PRIM;
  55. ev->prim = LLC_DATA_PRIM;
  56. ev->prim_type = LLC_PRIM_TYPE_REQ;
  57. skb->dev = llc->dev;
  58. rc = llc_conn_state_process(sk, skb);
  59. out:
  60. return rc;
  61. }
  62. /**
  63. * llc_establish_connection - Called by upper layer to establish a conn
  64. * @sk: connection
  65. * @lmac: local mac address
  66. * @dmac: destination mac address
  67. * @dsap: destination sap
  68. *
  69. * Upper layer calls this to establish an LLC connection with a remote
  70. * machine. This function packages a proper event and sends it connection
  71. * component state machine. Success or failure of connection
  72. * establishment will inform to upper layer via calling it's confirm
  73. * function and passing proper information.
  74. */
  75. int llc_establish_connection(struct sock *sk, u8 *lmac, u8 *dmac, u8 dsap)
  76. {
  77. int rc = -EISCONN;
  78. struct llc_addr laddr, daddr;
  79. struct sk_buff *skb;
  80. struct llc_sock *llc = llc_sk(sk);
  81. struct sock *existing;
  82. laddr.lsap = llc->sap->laddr.lsap;
  83. daddr.lsap = dsap;
  84. memcpy(daddr.mac, dmac, sizeof(daddr.mac));
  85. memcpy(laddr.mac, lmac, sizeof(laddr.mac));
  86. existing = llc_lookup_established(llc->sap, &daddr, &laddr);
  87. if (existing) {
  88. if (existing->sk_state == TCP_ESTABLISHED) {
  89. sk = existing;
  90. goto out_put;
  91. } else
  92. sock_put(existing);
  93. }
  94. sock_hold(sk);
  95. rc = -ENOMEM;
  96. skb = alloc_skb(0, GFP_ATOMIC);
  97. if (skb) {
  98. struct llc_conn_state_ev *ev = llc_conn_ev(skb);
  99. ev->type = LLC_CONN_EV_TYPE_PRIM;
  100. ev->prim = LLC_CONN_PRIM;
  101. ev->prim_type = LLC_PRIM_TYPE_REQ;
  102. skb_set_owner_w(skb, sk);
  103. rc = llc_conn_state_process(sk, skb);
  104. }
  105. out_put:
  106. sock_put(sk);
  107. return rc;
  108. }
  109. /**
  110. * llc_send_disc - Called by upper layer to close a connection
  111. * @sk: connection to be closed
  112. *
  113. * Upper layer calls this when it wants to close an established LLC
  114. * connection with a remote machine. This function packages a proper event
  115. * and sends it to connection component state machine. Returns 0 for
  116. * success, 1 otherwise.
  117. */
  118. int llc_send_disc(struct sock *sk)
  119. {
  120. u16 rc = 1;
  121. struct llc_conn_state_ev *ev;
  122. struct sk_buff *skb;
  123. sock_hold(sk);
  124. if (sk->sk_type != SOCK_STREAM || sk->sk_state != TCP_ESTABLISHED ||
  125. llc_sk(sk)->state == LLC_CONN_STATE_ADM ||
  126. llc_sk(sk)->state == LLC_CONN_OUT_OF_SVC)
  127. goto out;
  128. /*
  129. * Postpone unassigning the connection from its SAP and returning the
  130. * connection until all ACTIONs have been completely executed
  131. */
  132. skb = alloc_skb(0, GFP_ATOMIC);
  133. if (!skb)
  134. goto out;
  135. skb_set_owner_w(skb, sk);
  136. sk->sk_state = TCP_CLOSING;
  137. ev = llc_conn_ev(skb);
  138. ev->type = LLC_CONN_EV_TYPE_PRIM;
  139. ev->prim = LLC_DISC_PRIM;
  140. ev->prim_type = LLC_PRIM_TYPE_REQ;
  141. rc = llc_conn_state_process(sk, skb);
  142. out:
  143. sock_put(sk);
  144. return rc;
  145. }