llc_c_ev.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748
  1. /*
  2. * llc_c_ev.c - Connection component state transition event qualifiers
  3. *
  4. * A 'state' consists of a number of possible event matching functions,
  5. * the actions associated with each being executed when that event is
  6. * matched; a 'state machine' accepts events in a serial fashion from an
  7. * event queue. Each event is passed to each successive event matching
  8. * function until a match is made (the event matching function returns
  9. * success, or '0') or the list of event matching functions is exhausted.
  10. * If a match is made, the actions associated with the event are executed
  11. * and the state is changed to that event's transition state. Before some
  12. * events are recognized, even after a match has been made, a certain
  13. * number of 'event qualifier' functions must also be executed. If these
  14. * all execute successfully, then the event is finally executed.
  15. *
  16. * These event functions must return 0 for success, to show a matched
  17. * event, of 1 if the event does not match. Event qualifier functions
  18. * must return a 0 for success or a non-zero for failure. Each function
  19. * is simply responsible for verifying one single thing and returning
  20. * either a success or failure.
  21. *
  22. * All of followed event functions are described in 802.2 LLC Protocol
  23. * standard document except two functions that we added that will explain
  24. * in their comments, at below.
  25. *
  26. * Copyright (c) 1997 by Procom Technology, Inc.
  27. * 2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
  28. *
  29. * This program can be redistributed or modified under the terms of the
  30. * GNU General Public License as published by the Free Software Foundation.
  31. * This program is distributed without any warranty or implied warranty
  32. * of merchantability or fitness for a particular purpose.
  33. *
  34. * See the GNU General Public License for more details.
  35. */
  36. #include <linux/netdevice.h>
  37. #include <net/llc_conn.h>
  38. #include <net/llc_sap.h>
  39. #include <net/sock.h>
  40. #include <net/llc_c_ac.h>
  41. #include <net/llc_c_ev.h>
  42. #include <net/llc_pdu.h>
  43. #if 1
  44. #define dprintk(args...) printk(KERN_DEBUG args)
  45. #else
  46. #define dprintk(args...)
  47. #endif
  48. /**
  49. * llc_util_ns_inside_rx_window - check if sequence number is in rx window
  50. * @ns: sequence number of received pdu.
  51. * @vr: sequence number which receiver expects to receive.
  52. * @rw: receive window size of receiver.
  53. *
  54. * Checks if sequence number of received PDU is in range of receive
  55. * window. Returns 0 for success, 1 otherwise
  56. */
  57. static u16 llc_util_ns_inside_rx_window(u8 ns, u8 vr, u8 rw)
  58. {
  59. return !llc_circular_between(vr, ns,
  60. (vr + rw - 1) % LLC_2_SEQ_NBR_MODULO);
  61. }
  62. /**
  63. * llc_util_nr_inside_tx_window - check if sequence number is in tx window
  64. * @sk: current connection.
  65. * @nr: N(R) of received PDU.
  66. *
  67. * This routine checks if N(R) of received PDU is in range of transmit
  68. * window; on the other hand checks if received PDU acknowledges some
  69. * outstanding PDUs that are in transmit window. Returns 0 for success, 1
  70. * otherwise.
  71. */
  72. static u16 llc_util_nr_inside_tx_window(struct sock *sk, u8 nr)
  73. {
  74. u8 nr1, nr2;
  75. struct sk_buff *skb;
  76. struct llc_pdu_sn *pdu;
  77. struct llc_sock *llc = llc_sk(sk);
  78. int rc = 0;
  79. if (llc->dev->flags & IFF_LOOPBACK)
  80. goto out;
  81. rc = 1;
  82. if (skb_queue_empty(&llc->pdu_unack_q))
  83. goto out;
  84. skb = skb_peek(&llc->pdu_unack_q);
  85. pdu = llc_pdu_sn_hdr(skb);
  86. nr1 = LLC_I_GET_NS(pdu);
  87. skb = skb_peek_tail(&llc->pdu_unack_q);
  88. pdu = llc_pdu_sn_hdr(skb);
  89. nr2 = LLC_I_GET_NS(pdu);
  90. rc = !llc_circular_between(nr1, nr, (nr2 + 1) % LLC_2_SEQ_NBR_MODULO);
  91. out:
  92. return rc;
  93. }
  94. int llc_conn_ev_conn_req(struct sock *sk, struct sk_buff *skb)
  95. {
  96. const struct llc_conn_state_ev *ev = llc_conn_ev(skb);
  97. return ev->prim == LLC_CONN_PRIM &&
  98. ev->prim_type == LLC_PRIM_TYPE_REQ ? 0 : 1;
  99. }
  100. int llc_conn_ev_data_req(struct sock *sk, struct sk_buff *skb)
  101. {
  102. const struct llc_conn_state_ev *ev = llc_conn_ev(skb);
  103. return ev->prim == LLC_DATA_PRIM &&
  104. ev->prim_type == LLC_PRIM_TYPE_REQ ? 0 : 1;
  105. }
  106. int llc_conn_ev_disc_req(struct sock *sk, struct sk_buff *skb)
  107. {
  108. const struct llc_conn_state_ev *ev = llc_conn_ev(skb);
  109. return ev->prim == LLC_DISC_PRIM &&
  110. ev->prim_type == LLC_PRIM_TYPE_REQ ? 0 : 1;
  111. }
  112. int llc_conn_ev_rst_req(struct sock *sk, struct sk_buff *skb)
  113. {
  114. const struct llc_conn_state_ev *ev = llc_conn_ev(skb);
  115. return ev->prim == LLC_RESET_PRIM &&
  116. ev->prim_type == LLC_PRIM_TYPE_REQ ? 0 : 1;
  117. }
  118. int llc_conn_ev_local_busy_detected(struct sock *sk, struct sk_buff *skb)
  119. {
  120. const struct llc_conn_state_ev *ev = llc_conn_ev(skb);
  121. return ev->type == LLC_CONN_EV_TYPE_SIMPLE &&
  122. ev->prim_type == LLC_CONN_EV_LOCAL_BUSY_DETECTED ? 0 : 1;
  123. }
  124. int llc_conn_ev_local_busy_cleared(struct sock *sk, struct sk_buff *skb)
  125. {
  126. const struct llc_conn_state_ev *ev = llc_conn_ev(skb);
  127. return ev->type == LLC_CONN_EV_TYPE_SIMPLE &&
  128. ev->prim_type == LLC_CONN_EV_LOCAL_BUSY_CLEARED ? 0 : 1;
  129. }
  130. int llc_conn_ev_rx_bad_pdu(struct sock *sk, struct sk_buff *skb)
  131. {
  132. return 1;
  133. }
  134. int llc_conn_ev_rx_disc_cmd_pbit_set_x(struct sock *sk, struct sk_buff *skb)
  135. {
  136. const struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
  137. return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_U(pdu) &&
  138. LLC_U_PDU_CMD(pdu) == LLC_2_PDU_CMD_DISC ? 0 : 1;
  139. }
  140. int llc_conn_ev_rx_dm_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb)
  141. {
  142. const struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
  143. return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_U(pdu) &&
  144. LLC_U_PDU_RSP(pdu) == LLC_2_PDU_RSP_DM ? 0 : 1;
  145. }
  146. int llc_conn_ev_rx_frmr_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb)
  147. {
  148. const struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
  149. return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_U(pdu) &&
  150. LLC_U_PDU_RSP(pdu) == LLC_2_PDU_RSP_FRMR ? 0 : 1;
  151. }
  152. int llc_conn_ev_rx_i_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb)
  153. {
  154. const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
  155. return llc_conn_space(sk, skb) &&
  156. LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
  157. LLC_I_PF_IS_0(pdu) &&
  158. LLC_I_GET_NS(pdu) == llc_sk(sk)->vR ? 0 : 1;
  159. }
  160. int llc_conn_ev_rx_i_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb)
  161. {
  162. const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
  163. return llc_conn_space(sk, skb) &&
  164. LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
  165. LLC_I_PF_IS_1(pdu) &&
  166. LLC_I_GET_NS(pdu) == llc_sk(sk)->vR ? 0 : 1;
  167. }
  168. int llc_conn_ev_rx_i_cmd_pbit_set_0_unexpd_ns(struct sock *sk,
  169. struct sk_buff *skb)
  170. {
  171. const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
  172. const u8 vr = llc_sk(sk)->vR;
  173. const u8 ns = LLC_I_GET_NS(pdu);
  174. return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
  175. LLC_I_PF_IS_0(pdu) && ns != vr &&
  176. !llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1;
  177. }
  178. int llc_conn_ev_rx_i_cmd_pbit_set_1_unexpd_ns(struct sock *sk,
  179. struct sk_buff *skb)
  180. {
  181. const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
  182. const u8 vr = llc_sk(sk)->vR;
  183. const u8 ns = LLC_I_GET_NS(pdu);
  184. return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
  185. LLC_I_PF_IS_1(pdu) && ns != vr &&
  186. !llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1;
  187. }
  188. int llc_conn_ev_rx_i_cmd_pbit_set_x_inval_ns(struct sock *sk,
  189. struct sk_buff *skb)
  190. {
  191. const struct llc_pdu_sn * pdu = llc_pdu_sn_hdr(skb);
  192. const u8 vr = llc_sk(sk)->vR;
  193. const u8 ns = LLC_I_GET_NS(pdu);
  194. const u16 rc = LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
  195. ns != vr &&
  196. llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1;
  197. if (!rc)
  198. dprintk("%s: matched, state=%d, ns=%d, vr=%d\n",
  199. __FUNCTION__, llc_sk(sk)->state, ns, vr);
  200. return rc;
  201. }
  202. int llc_conn_ev_rx_i_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb)
  203. {
  204. const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
  205. return llc_conn_space(sk, skb) &&
  206. LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
  207. LLC_I_PF_IS_0(pdu) &&
  208. LLC_I_GET_NS(pdu) == llc_sk(sk)->vR ? 0 : 1;
  209. }
  210. int llc_conn_ev_rx_i_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb)
  211. {
  212. const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
  213. return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
  214. LLC_I_PF_IS_1(pdu) &&
  215. LLC_I_GET_NS(pdu) == llc_sk(sk)->vR ? 0 : 1;
  216. }
  217. int llc_conn_ev_rx_i_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb)
  218. {
  219. const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
  220. return llc_conn_space(sk, skb) &&
  221. LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
  222. LLC_I_GET_NS(pdu) == llc_sk(sk)->vR ? 0 : 1;
  223. }
  224. int llc_conn_ev_rx_i_rsp_fbit_set_0_unexpd_ns(struct sock *sk,
  225. struct sk_buff *skb)
  226. {
  227. const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
  228. const u8 vr = llc_sk(sk)->vR;
  229. const u8 ns = LLC_I_GET_NS(pdu);
  230. return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
  231. LLC_I_PF_IS_0(pdu) && ns != vr &&
  232. !llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1;
  233. }
  234. int llc_conn_ev_rx_i_rsp_fbit_set_1_unexpd_ns(struct sock *sk,
  235. struct sk_buff *skb)
  236. {
  237. const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
  238. const u8 vr = llc_sk(sk)->vR;
  239. const u8 ns = LLC_I_GET_NS(pdu);
  240. return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
  241. LLC_I_PF_IS_1(pdu) && ns != vr &&
  242. !llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1;
  243. }
  244. int llc_conn_ev_rx_i_rsp_fbit_set_x_unexpd_ns(struct sock *sk,
  245. struct sk_buff *skb)
  246. {
  247. const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
  248. const u8 vr = llc_sk(sk)->vR;
  249. const u8 ns = LLC_I_GET_NS(pdu);
  250. return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) && ns != vr &&
  251. !llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1;
  252. }
  253. int llc_conn_ev_rx_i_rsp_fbit_set_x_inval_ns(struct sock *sk,
  254. struct sk_buff *skb)
  255. {
  256. const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
  257. const u8 vr = llc_sk(sk)->vR;
  258. const u8 ns = LLC_I_GET_NS(pdu);
  259. const u16 rc = LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
  260. ns != vr &&
  261. llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1;
  262. if (!rc)
  263. dprintk("%s: matched, state=%d, ns=%d, vr=%d\n",
  264. __FUNCTION__, llc_sk(sk)->state, ns, vr);
  265. return rc;
  266. }
  267. int llc_conn_ev_rx_rej_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb)
  268. {
  269. const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
  270. return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
  271. LLC_S_PF_IS_0(pdu) &&
  272. LLC_S_PDU_CMD(pdu) == LLC_2_PDU_CMD_REJ ? 0 : 1;
  273. }
  274. int llc_conn_ev_rx_rej_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb)
  275. {
  276. const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
  277. return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
  278. LLC_S_PF_IS_1(pdu) &&
  279. LLC_S_PDU_CMD(pdu) == LLC_2_PDU_CMD_REJ ? 0 : 1;
  280. }
  281. int llc_conn_ev_rx_rej_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb)
  282. {
  283. const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
  284. return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
  285. LLC_S_PF_IS_0(pdu) &&
  286. LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_REJ ? 0 : 1;
  287. }
  288. int llc_conn_ev_rx_rej_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb)
  289. {
  290. const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
  291. return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
  292. LLC_S_PF_IS_1(pdu) &&
  293. LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_REJ ? 0 : 1;
  294. }
  295. int llc_conn_ev_rx_rej_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb)
  296. {
  297. const struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
  298. return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
  299. LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_REJ ? 0 : 1;
  300. }
  301. int llc_conn_ev_rx_rnr_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb)
  302. {
  303. const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
  304. return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
  305. LLC_S_PF_IS_0(pdu) &&
  306. LLC_S_PDU_CMD(pdu) == LLC_2_PDU_CMD_RNR ? 0 : 1;
  307. }
  308. int llc_conn_ev_rx_rnr_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb)
  309. {
  310. const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
  311. return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
  312. LLC_S_PF_IS_1(pdu) &&
  313. LLC_S_PDU_CMD(pdu) == LLC_2_PDU_CMD_RNR ? 0 : 1;
  314. }
  315. int llc_conn_ev_rx_rnr_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb)
  316. {
  317. const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
  318. return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
  319. LLC_S_PF_IS_0(pdu) &&
  320. LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_RNR ? 0 : 1;
  321. }
  322. int llc_conn_ev_rx_rnr_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb)
  323. {
  324. const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
  325. return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
  326. LLC_S_PF_IS_1(pdu) &&
  327. LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_RNR ? 0 : 1;
  328. }
  329. int llc_conn_ev_rx_rr_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb)
  330. {
  331. const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
  332. return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
  333. LLC_S_PF_IS_0(pdu) &&
  334. LLC_S_PDU_CMD(pdu) == LLC_2_PDU_CMD_RR ? 0 : 1;
  335. }
  336. int llc_conn_ev_rx_rr_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb)
  337. {
  338. const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
  339. return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
  340. LLC_S_PF_IS_1(pdu) &&
  341. LLC_S_PDU_CMD(pdu) == LLC_2_PDU_CMD_RR ? 0 : 1;
  342. }
  343. int llc_conn_ev_rx_rr_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb)
  344. {
  345. const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
  346. return llc_conn_space(sk, skb) &&
  347. LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
  348. LLC_S_PF_IS_0(pdu) &&
  349. LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_RR ? 0 : 1;
  350. }
  351. int llc_conn_ev_rx_rr_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb)
  352. {
  353. const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
  354. return llc_conn_space(sk, skb) &&
  355. LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
  356. LLC_S_PF_IS_1(pdu) &&
  357. LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_RR ? 0 : 1;
  358. }
  359. int llc_conn_ev_rx_sabme_cmd_pbit_set_x(struct sock *sk, struct sk_buff *skb)
  360. {
  361. const struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
  362. return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_U(pdu) &&
  363. LLC_U_PDU_CMD(pdu) == LLC_2_PDU_CMD_SABME ? 0 : 1;
  364. }
  365. int llc_conn_ev_rx_ua_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb)
  366. {
  367. struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
  368. return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_U(pdu) &&
  369. LLC_U_PDU_RSP(pdu) == LLC_2_PDU_RSP_UA ? 0 : 1;
  370. }
  371. int llc_conn_ev_rx_xxx_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb)
  372. {
  373. u16 rc = 1;
  374. const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
  375. if (LLC_PDU_IS_CMD(pdu)) {
  376. if (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu)) {
  377. if (LLC_I_PF_IS_1(pdu))
  378. rc = 0;
  379. } else if (LLC_PDU_TYPE_IS_U(pdu) && LLC_U_PF_IS_1(pdu))
  380. rc = 0;
  381. }
  382. return rc;
  383. }
  384. int llc_conn_ev_rx_xxx_cmd_pbit_set_x(struct sock *sk, struct sk_buff *skb)
  385. {
  386. u16 rc = 1;
  387. const struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
  388. if (LLC_PDU_IS_CMD(pdu)) {
  389. if (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu))
  390. rc = 0;
  391. else if (LLC_PDU_TYPE_IS_U(pdu))
  392. switch (LLC_U_PDU_CMD(pdu)) {
  393. case LLC_2_PDU_CMD_SABME:
  394. case LLC_2_PDU_CMD_DISC:
  395. rc = 0;
  396. break;
  397. }
  398. }
  399. return rc;
  400. }
  401. int llc_conn_ev_rx_xxx_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb)
  402. {
  403. u16 rc = 1;
  404. const struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
  405. if (LLC_PDU_IS_RSP(pdu)) {
  406. if (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu))
  407. rc = 0;
  408. else if (LLC_PDU_TYPE_IS_U(pdu))
  409. switch (LLC_U_PDU_RSP(pdu)) {
  410. case LLC_2_PDU_RSP_UA:
  411. case LLC_2_PDU_RSP_DM:
  412. case LLC_2_PDU_RSP_FRMR:
  413. rc = 0;
  414. break;
  415. }
  416. }
  417. return rc;
  418. }
  419. int llc_conn_ev_rx_zzz_cmd_pbit_set_x_inval_nr(struct sock *sk,
  420. struct sk_buff *skb)
  421. {
  422. u16 rc = 1;
  423. const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
  424. const u8 vs = llc_sk(sk)->vS;
  425. const u8 nr = LLC_I_GET_NR(pdu);
  426. if (LLC_PDU_IS_CMD(pdu) &&
  427. (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu)) &&
  428. nr != vs && llc_util_nr_inside_tx_window(sk, nr)) {
  429. dprintk("%s: matched, state=%d, vs=%d, nr=%d\n",
  430. __FUNCTION__, llc_sk(sk)->state, vs, nr);
  431. rc = 0;
  432. }
  433. return rc;
  434. }
  435. int llc_conn_ev_rx_zzz_rsp_fbit_set_x_inval_nr(struct sock *sk,
  436. struct sk_buff *skb)
  437. {
  438. u16 rc = 1;
  439. const struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
  440. const u8 vs = llc_sk(sk)->vS;
  441. const u8 nr = LLC_I_GET_NR(pdu);
  442. if (LLC_PDU_IS_RSP(pdu) &&
  443. (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu)) &&
  444. nr != vs && llc_util_nr_inside_tx_window(sk, nr)) {
  445. rc = 0;
  446. dprintk("%s: matched, state=%d, vs=%d, nr=%d\n",
  447. __FUNCTION__, llc_sk(sk)->state, vs, nr);
  448. }
  449. return rc;
  450. }
  451. int llc_conn_ev_rx_any_frame(struct sock *sk, struct sk_buff *skb)
  452. {
  453. return 0;
  454. }
  455. int llc_conn_ev_p_tmr_exp(struct sock *sk, struct sk_buff *skb)
  456. {
  457. const struct llc_conn_state_ev *ev = llc_conn_ev(skb);
  458. return ev->type != LLC_CONN_EV_TYPE_P_TMR;
  459. }
  460. int llc_conn_ev_ack_tmr_exp(struct sock *sk, struct sk_buff *skb)
  461. {
  462. const struct llc_conn_state_ev *ev = llc_conn_ev(skb);
  463. return ev->type != LLC_CONN_EV_TYPE_ACK_TMR;
  464. }
  465. int llc_conn_ev_rej_tmr_exp(struct sock *sk, struct sk_buff *skb)
  466. {
  467. const struct llc_conn_state_ev *ev = llc_conn_ev(skb);
  468. return ev->type != LLC_CONN_EV_TYPE_REJ_TMR;
  469. }
  470. int llc_conn_ev_busy_tmr_exp(struct sock *sk, struct sk_buff *skb)
  471. {
  472. const struct llc_conn_state_ev *ev = llc_conn_ev(skb);
  473. return ev->type != LLC_CONN_EV_TYPE_BUSY_TMR;
  474. }
  475. int llc_conn_ev_init_p_f_cycle(struct sock *sk, struct sk_buff *skb)
  476. {
  477. return 1;
  478. }
  479. int llc_conn_ev_tx_buffer_full(struct sock *sk, struct sk_buff *skb)
  480. {
  481. const struct llc_conn_state_ev *ev = llc_conn_ev(skb);
  482. return ev->type == LLC_CONN_EV_TYPE_SIMPLE &&
  483. ev->prim_type == LLC_CONN_EV_TX_BUFF_FULL ? 0 : 1;
  484. }
  485. /* Event qualifier functions
  486. *
  487. * these functions simply verify the value of a state flag associated with
  488. * the connection and return either a 0 for success or a non-zero value
  489. * for not-success; verify the event is the type we expect
  490. */
  491. int llc_conn_ev_qlfy_data_flag_eq_1(struct sock *sk, struct sk_buff *skb)
  492. {
  493. return llc_sk(sk)->data_flag != 1;
  494. }
  495. int llc_conn_ev_qlfy_data_flag_eq_0(struct sock *sk, struct sk_buff *skb)
  496. {
  497. return llc_sk(sk)->data_flag;
  498. }
  499. int llc_conn_ev_qlfy_data_flag_eq_2(struct sock *sk, struct sk_buff *skb)
  500. {
  501. return llc_sk(sk)->data_flag != 2;
  502. }
  503. int llc_conn_ev_qlfy_p_flag_eq_1(struct sock *sk, struct sk_buff *skb)
  504. {
  505. return llc_sk(sk)->p_flag != 1;
  506. }
  507. /**
  508. * conn_ev_qlfy_last_frame_eq_1 - checks if frame is last in tx window
  509. * @sk: current connection structure.
  510. * @skb: current event.
  511. *
  512. * This function determines when frame which is sent, is last frame of
  513. * transmit window, if it is then this function return zero else return
  514. * one. This function is used for sending last frame of transmit window
  515. * as I-format command with p-bit set to one. Returns 0 if frame is last
  516. * frame, 1 otherwise.
  517. */
  518. int llc_conn_ev_qlfy_last_frame_eq_1(struct sock *sk, struct sk_buff *skb)
  519. {
  520. return !(skb_queue_len(&llc_sk(sk)->pdu_unack_q) + 1 == llc_sk(sk)->k);
  521. }
  522. /**
  523. * conn_ev_qlfy_last_frame_eq_0 - checks if frame isn't last in tx window
  524. * @sk: current connection structure.
  525. * @skb: current event.
  526. *
  527. * This function determines when frame which is sent, isn't last frame of
  528. * transmit window, if it isn't then this function return zero else return
  529. * one. Returns 0 if frame isn't last frame, 1 otherwise.
  530. */
  531. int llc_conn_ev_qlfy_last_frame_eq_0(struct sock *sk, struct sk_buff *skb)
  532. {
  533. return skb_queue_len(&llc_sk(sk)->pdu_unack_q) + 1 == llc_sk(sk)->k;
  534. }
  535. int llc_conn_ev_qlfy_p_flag_eq_0(struct sock *sk, struct sk_buff *skb)
  536. {
  537. return llc_sk(sk)->p_flag;
  538. }
  539. int llc_conn_ev_qlfy_p_flag_eq_f(struct sock *sk, struct sk_buff *skb)
  540. {
  541. u8 f_bit;
  542. llc_pdu_decode_pf_bit(skb, &f_bit);
  543. return llc_sk(sk)->p_flag == f_bit ? 0 : 1;
  544. }
  545. int llc_conn_ev_qlfy_remote_busy_eq_0(struct sock *sk, struct sk_buff *skb)
  546. {
  547. return llc_sk(sk)->remote_busy_flag;
  548. }
  549. int llc_conn_ev_qlfy_remote_busy_eq_1(struct sock *sk, struct sk_buff *skb)
  550. {
  551. return !llc_sk(sk)->remote_busy_flag;
  552. }
  553. int llc_conn_ev_qlfy_retry_cnt_lt_n2(struct sock *sk, struct sk_buff *skb)
  554. {
  555. return !(llc_sk(sk)->retry_count < llc_sk(sk)->n2);
  556. }
  557. int llc_conn_ev_qlfy_retry_cnt_gte_n2(struct sock *sk, struct sk_buff *skb)
  558. {
  559. return !(llc_sk(sk)->retry_count >= llc_sk(sk)->n2);
  560. }
  561. int llc_conn_ev_qlfy_s_flag_eq_1(struct sock *sk, struct sk_buff *skb)
  562. {
  563. return !llc_sk(sk)->s_flag;
  564. }
  565. int llc_conn_ev_qlfy_s_flag_eq_0(struct sock *sk, struct sk_buff *skb)
  566. {
  567. return llc_sk(sk)->s_flag;
  568. }
  569. int llc_conn_ev_qlfy_cause_flag_eq_1(struct sock *sk, struct sk_buff *skb)
  570. {
  571. return !llc_sk(sk)->cause_flag;
  572. }
  573. int llc_conn_ev_qlfy_cause_flag_eq_0(struct sock *sk, struct sk_buff *skb)
  574. {
  575. return llc_sk(sk)->cause_flag;
  576. }
  577. int llc_conn_ev_qlfy_set_status_conn(struct sock *sk, struct sk_buff *skb)
  578. {
  579. struct llc_conn_state_ev *ev = llc_conn_ev(skb);
  580. ev->status = LLC_STATUS_CONN;
  581. return 0;
  582. }
  583. int llc_conn_ev_qlfy_set_status_disc(struct sock *sk, struct sk_buff *skb)
  584. {
  585. struct llc_conn_state_ev *ev = llc_conn_ev(skb);
  586. ev->status = LLC_STATUS_DISC;
  587. return 0;
  588. }
  589. int llc_conn_ev_qlfy_set_status_failed(struct sock *sk, struct sk_buff *skb)
  590. {
  591. struct llc_conn_state_ev *ev = llc_conn_ev(skb);
  592. ev->status = LLC_STATUS_FAILED;
  593. return 0;
  594. }
  595. int llc_conn_ev_qlfy_set_status_remote_busy(struct sock *sk,
  596. struct sk_buff *skb)
  597. {
  598. struct llc_conn_state_ev *ev = llc_conn_ev(skb);
  599. ev->status = LLC_STATUS_REMOTE_BUSY;
  600. return 0;
  601. }
  602. int llc_conn_ev_qlfy_set_status_refuse(struct sock *sk, struct sk_buff *skb)
  603. {
  604. struct llc_conn_state_ev *ev = llc_conn_ev(skb);
  605. ev->status = LLC_STATUS_REFUSE;
  606. return 0;
  607. }
  608. int llc_conn_ev_qlfy_set_status_conflict(struct sock *sk, struct sk_buff *skb)
  609. {
  610. struct llc_conn_state_ev *ev = llc_conn_ev(skb);
  611. ev->status = LLC_STATUS_CONFLICT;
  612. return 0;
  613. }
  614. int llc_conn_ev_qlfy_set_status_rst_done(struct sock *sk, struct sk_buff *skb)
  615. {
  616. struct llc_conn_state_ev *ev = llc_conn_ev(skb);
  617. ev->status = LLC_STATUS_RESET_DONE;
  618. return 0;
  619. }