llc_if.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  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 <linux/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. * This function always consumes a reference to the skb.
  42. */
  43. int llc_build_and_send_pkt(struct sock *sk, struct sk_buff *skb)
  44. {
  45. struct llc_conn_state_ev *ev;
  46. int rc = -ECONNABORTED;
  47. struct llc_sock *llc = llc_sk(sk);
  48. if (unlikely(llc->state == LLC_CONN_STATE_ADM))
  49. goto out_free;
  50. rc = -EBUSY;
  51. if (unlikely(llc_data_accept_state(llc->state) || /* data_conn_refuse */
  52. llc->p_flag)) {
  53. llc->failed_data_req = 1;
  54. goto out_free;
  55. }
  56. ev = llc_conn_ev(skb);
  57. ev->type = LLC_CONN_EV_TYPE_PRIM;
  58. ev->prim = LLC_DATA_PRIM;
  59. ev->prim_type = LLC_PRIM_TYPE_REQ;
  60. skb->dev = llc->dev;
  61. return llc_conn_state_process(sk, skb);
  62. out_free:
  63. kfree_skb(skb);
  64. return rc;
  65. }
  66. /**
  67. * llc_establish_connection - Called by upper layer to establish a conn
  68. * @sk: connection
  69. * @lmac: local mac address
  70. * @dmac: destination mac address
  71. * @dsap: destination sap
  72. *
  73. * Upper layer calls this to establish an LLC connection with a remote
  74. * machine. This function packages a proper event and sends it connection
  75. * component state machine. Success or failure of connection
  76. * establishment will inform to upper layer via calling it's confirm
  77. * function and passing proper information.
  78. */
  79. int llc_establish_connection(struct sock *sk, u8 *lmac, u8 *dmac, u8 dsap)
  80. {
  81. int rc = -EISCONN;
  82. struct llc_addr laddr, daddr;
  83. struct sk_buff *skb;
  84. struct llc_sock *llc = llc_sk(sk);
  85. struct sock *existing;
  86. laddr.lsap = llc->sap->laddr.lsap;
  87. daddr.lsap = dsap;
  88. memcpy(daddr.mac, dmac, sizeof(daddr.mac));
  89. memcpy(laddr.mac, lmac, sizeof(laddr.mac));
  90. existing = llc_lookup_established(llc->sap, &daddr, &laddr);
  91. if (existing) {
  92. if (existing->sk_state == TCP_ESTABLISHED) {
  93. sk = existing;
  94. goto out_put;
  95. } else
  96. sock_put(existing);
  97. }
  98. sock_hold(sk);
  99. rc = -ENOMEM;
  100. skb = alloc_skb(0, GFP_ATOMIC);
  101. if (skb) {
  102. struct llc_conn_state_ev *ev = llc_conn_ev(skb);
  103. ev->type = LLC_CONN_EV_TYPE_PRIM;
  104. ev->prim = LLC_CONN_PRIM;
  105. ev->prim_type = LLC_PRIM_TYPE_REQ;
  106. skb_set_owner_w(skb, sk);
  107. rc = llc_conn_state_process(sk, skb);
  108. }
  109. out_put:
  110. sock_put(sk);
  111. return rc;
  112. }
  113. /**
  114. * llc_send_disc - Called by upper layer to close a connection
  115. * @sk: connection to be closed
  116. *
  117. * Upper layer calls this when it wants to close an established LLC
  118. * connection with a remote machine. This function packages a proper event
  119. * and sends it to connection component state machine. Returns 0 for
  120. * success, 1 otherwise.
  121. */
  122. int llc_send_disc(struct sock *sk)
  123. {
  124. u16 rc = 1;
  125. struct llc_conn_state_ev *ev;
  126. struct sk_buff *skb;
  127. sock_hold(sk);
  128. if (sk->sk_type != SOCK_STREAM || sk->sk_state != TCP_ESTABLISHED ||
  129. llc_sk(sk)->state == LLC_CONN_STATE_ADM ||
  130. llc_sk(sk)->state == LLC_CONN_OUT_OF_SVC)
  131. goto out;
  132. /*
  133. * Postpone unassigning the connection from its SAP and returning the
  134. * connection until all ACTIONs have been completely executed
  135. */
  136. skb = alloc_skb(0, GFP_ATOMIC);
  137. if (!skb)
  138. goto out;
  139. skb_set_owner_w(skb, sk);
  140. sk->sk_state = TCP_CLOSING;
  141. ev = llc_conn_ev(skb);
  142. ev->type = LLC_CONN_EV_TYPE_PRIM;
  143. ev->prim = LLC_DISC_PRIM;
  144. ev->prim_type = LLC_PRIM_TYPE_REQ;
  145. rc = llc_conn_state_process(sk, skb);
  146. out:
  147. sock_put(sk);
  148. return rc;
  149. }