llc_if.c 4.4 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/config.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. u8 llc_mac_null_var[IFHWADDRLEN];
  29. /**
  30. * llc_build_and_send_pkt - Connection data sending for upper layers.
  31. * @sk: connection
  32. * @skb: packet to send
  33. *
  34. * This function is called when upper layer wants to send data using
  35. * connection oriented communication mode. During sending data, connection
  36. * will be locked and received frames and expired timers will be queued.
  37. * Returns 0 for success, -ECONNABORTED when the connection already
  38. * closed and -EBUSY when sending data is not permitted in this state or
  39. * LLC has send an I pdu with p bit set to 1 and is waiting for it's
  40. * response.
  41. */
  42. int llc_build_and_send_pkt(struct sock *sk, struct sk_buff *skb)
  43. {
  44. struct llc_conn_state_ev *ev;
  45. int rc = -ECONNABORTED;
  46. struct llc_sock *llc = llc_sk(sk);
  47. if (llc->state == LLC_CONN_STATE_ADM)
  48. goto out;
  49. rc = -EBUSY;
  50. if (llc_data_accept_state(llc->state)) { /* data_conn_refuse */
  51. llc->failed_data_req = 1;
  52. goto out;
  53. }
  54. if (llc->p_flag) {
  55. llc->failed_data_req = 1;
  56. goto out;
  57. }
  58. ev = llc_conn_ev(skb);
  59. ev->type = LLC_CONN_EV_TYPE_PRIM;
  60. ev->prim = LLC_DATA_PRIM;
  61. ev->prim_type = LLC_PRIM_TYPE_REQ;
  62. skb->dev = llc->dev;
  63. rc = llc_conn_state_process(sk, skb);
  64. out:
  65. return rc;
  66. }
  67. /**
  68. * llc_establish_connection - Called by upper layer to establish a conn
  69. * @sk: connection
  70. * @lmac: local mac address
  71. * @dmac: destination mac address
  72. * @dsap: destination sap
  73. *
  74. * Upper layer calls this to establish an LLC connection with a remote
  75. * machine. This function packages a proper event and sends it connection
  76. * component state machine. Success or failure of connection
  77. * establishment will inform to upper layer via calling it's confirm
  78. * function and passing proper information.
  79. */
  80. int llc_establish_connection(struct sock *sk, u8 *lmac, u8 *dmac, u8 dsap)
  81. {
  82. int rc = -EISCONN;
  83. struct llc_addr laddr, daddr;
  84. struct sk_buff *skb;
  85. struct llc_sock *llc = llc_sk(sk);
  86. struct sock *existing;
  87. laddr.lsap = llc->sap->laddr.lsap;
  88. daddr.lsap = dsap;
  89. memcpy(daddr.mac, dmac, sizeof(daddr.mac));
  90. memcpy(laddr.mac, lmac, sizeof(laddr.mac));
  91. existing = llc_lookup_established(llc->sap, &daddr, &laddr);
  92. if (existing) {
  93. if (existing->sk_state == TCP_ESTABLISHED) {
  94. sk = existing;
  95. goto out_put;
  96. } else
  97. sock_put(existing);
  98. }
  99. sock_hold(sk);
  100. rc = -ENOMEM;
  101. skb = alloc_skb(0, GFP_ATOMIC);
  102. if (skb) {
  103. struct llc_conn_state_ev *ev = llc_conn_ev(skb);
  104. ev->type = LLC_CONN_EV_TYPE_PRIM;
  105. ev->prim = LLC_CONN_PRIM;
  106. ev->prim_type = LLC_PRIM_TYPE_REQ;
  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. sk->sk_state = TCP_CLOSING;
  140. ev = llc_conn_ev(skb);
  141. ev->type = LLC_CONN_EV_TYPE_PRIM;
  142. ev->prim = LLC_DISC_PRIM;
  143. ev->prim_type = LLC_PRIM_TYPE_REQ;
  144. rc = llc_conn_state_process(sk, skb);
  145. out:
  146. sock_put(sk);
  147. return rc;
  148. }