llc_if.c 4.4 KB

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