llc_c_ac.c 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452
  1. /*
  2. * llc_c_ac.c - actions performed during connection state transition.
  3. *
  4. * Description:
  5. * Functions in this module are implementation of connection component actions
  6. * Details of actions can be found in IEEE-802.2 standard document.
  7. * All functions have one connection and one event as input argument. All of
  8. * them return 0 On success and 1 otherwise.
  9. *
  10. * Copyright (c) 1997 by Procom Technology, Inc.
  11. * 2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
  12. *
  13. * This program can be redistributed or modified under the terms of the
  14. * GNU General Public License as published by the Free Software Foundation.
  15. * This program is distributed without any warranty or implied warranty
  16. * of merchantability or fitness for a particular purpose.
  17. *
  18. * See the GNU General Public License for more details.
  19. */
  20. #include <linux/netdevice.h>
  21. #include <net/llc_conn.h>
  22. #include <net/llc_sap.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/llc_pdu.h>
  28. #include <net/llc.h>
  29. #include "llc_output.h"
  30. static int llc_conn_ac_inc_vs_by_1(struct sock *sk, struct sk_buff *skb);
  31. static void llc_process_tmr_ev(struct sock *sk, struct sk_buff *skb);
  32. static int llc_conn_ac_data_confirm(struct sock *sk, struct sk_buff *ev);
  33. static int llc_conn_ac_inc_npta_value(struct sock *sk, struct sk_buff *skb);
  34. static int llc_conn_ac_send_rr_rsp_f_set_ackpf(struct sock *sk,
  35. struct sk_buff *skb);
  36. static int llc_conn_ac_set_p_flag_1(struct sock *sk, struct sk_buff *skb);
  37. #define INCORRECT 0
  38. int llc_conn_ac_clear_remote_busy(struct sock *sk, struct sk_buff *skb)
  39. {
  40. struct llc_sock *llc = llc_sk(sk);
  41. if (llc->remote_busy_flag) {
  42. u8 nr;
  43. struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
  44. llc->remote_busy_flag = 0;
  45. del_timer(&llc->busy_state_timer.timer);
  46. nr = LLC_I_GET_NR(pdu);
  47. llc_conn_resend_i_pdu_as_cmd(sk, nr, 0);
  48. }
  49. return 0;
  50. }
  51. int llc_conn_ac_conn_ind(struct sock *sk, struct sk_buff *skb)
  52. {
  53. int rc = -ENOTCONN;
  54. u8 dsap;
  55. struct llc_sap *sap;
  56. llc_pdu_decode_dsap(skb, &dsap);
  57. sap = llc_sap_find(dsap);
  58. if (sap) {
  59. struct llc_conn_state_ev *ev = llc_conn_ev(skb);
  60. struct llc_sock *llc = llc_sk(sk);
  61. llc_pdu_decode_sa(skb, llc->daddr.mac);
  62. llc_pdu_decode_da(skb, llc->laddr.mac);
  63. llc->dev = skb->dev;
  64. ev->ind_prim = LLC_CONN_PRIM;
  65. rc = 0;
  66. }
  67. return rc;
  68. }
  69. int llc_conn_ac_conn_confirm(struct sock *sk, struct sk_buff *skb)
  70. {
  71. struct llc_conn_state_ev *ev = llc_conn_ev(skb);
  72. ev->cfm_prim = LLC_CONN_PRIM;
  73. return 0;
  74. }
  75. static int llc_conn_ac_data_confirm(struct sock *sk, struct sk_buff *skb)
  76. {
  77. struct llc_conn_state_ev *ev = llc_conn_ev(skb);
  78. ev->cfm_prim = LLC_DATA_PRIM;
  79. return 0;
  80. }
  81. int llc_conn_ac_data_ind(struct sock *sk, struct sk_buff *skb)
  82. {
  83. llc_conn_rtn_pdu(sk, skb);
  84. return 0;
  85. }
  86. int llc_conn_ac_disc_ind(struct sock *sk, struct sk_buff *skb)
  87. {
  88. struct llc_conn_state_ev *ev = llc_conn_ev(skb);
  89. u8 reason = 0;
  90. int rc = 0;
  91. if (ev->type == LLC_CONN_EV_TYPE_PDU) {
  92. struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
  93. if (LLC_PDU_IS_RSP(pdu) &&
  94. LLC_PDU_TYPE_IS_U(pdu) &&
  95. LLC_U_PDU_RSP(pdu) == LLC_2_PDU_RSP_DM)
  96. reason = LLC_DISC_REASON_RX_DM_RSP_PDU;
  97. else if (LLC_PDU_IS_CMD(pdu) &&
  98. LLC_PDU_TYPE_IS_U(pdu) &&
  99. LLC_U_PDU_CMD(pdu) == LLC_2_PDU_CMD_DISC)
  100. reason = LLC_DISC_REASON_RX_DISC_CMD_PDU;
  101. } else if (ev->type == LLC_CONN_EV_TYPE_ACK_TMR)
  102. reason = LLC_DISC_REASON_ACK_TMR_EXP;
  103. else
  104. rc = -EINVAL;
  105. if (!rc) {
  106. ev->reason = reason;
  107. ev->ind_prim = LLC_DISC_PRIM;
  108. }
  109. return rc;
  110. }
  111. int llc_conn_ac_disc_confirm(struct sock *sk, struct sk_buff *skb)
  112. {
  113. struct llc_conn_state_ev *ev = llc_conn_ev(skb);
  114. ev->reason = ev->status;
  115. ev->cfm_prim = LLC_DISC_PRIM;
  116. return 0;
  117. }
  118. int llc_conn_ac_rst_ind(struct sock *sk, struct sk_buff *skb)
  119. {
  120. u8 reason = 0;
  121. int rc = 1;
  122. struct llc_conn_state_ev *ev = llc_conn_ev(skb);
  123. struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
  124. struct llc_sock *llc = llc_sk(sk);
  125. switch (ev->type) {
  126. case LLC_CONN_EV_TYPE_PDU:
  127. if (LLC_PDU_IS_RSP(pdu) &&
  128. LLC_PDU_TYPE_IS_U(pdu) &&
  129. LLC_U_PDU_RSP(pdu) == LLC_2_PDU_RSP_FRMR) {
  130. reason = LLC_RESET_REASON_LOCAL;
  131. rc = 0;
  132. } else if (LLC_PDU_IS_CMD(pdu) &&
  133. LLC_PDU_TYPE_IS_U(pdu) &&
  134. LLC_U_PDU_CMD(pdu) == LLC_2_PDU_CMD_SABME) {
  135. reason = LLC_RESET_REASON_REMOTE;
  136. rc = 0;
  137. }
  138. break;
  139. case LLC_CONN_EV_TYPE_ACK_TMR:
  140. case LLC_CONN_EV_TYPE_P_TMR:
  141. case LLC_CONN_EV_TYPE_REJ_TMR:
  142. case LLC_CONN_EV_TYPE_BUSY_TMR:
  143. if (llc->retry_count > llc->n2) {
  144. reason = LLC_RESET_REASON_LOCAL;
  145. rc = 0;
  146. }
  147. break;
  148. }
  149. if (!rc) {
  150. ev->reason = reason;
  151. ev->ind_prim = LLC_RESET_PRIM;
  152. }
  153. return rc;
  154. }
  155. int llc_conn_ac_rst_confirm(struct sock *sk, struct sk_buff *skb)
  156. {
  157. struct llc_conn_state_ev *ev = llc_conn_ev(skb);
  158. ev->reason = 0;
  159. ev->cfm_prim = LLC_RESET_PRIM;
  160. return 0;
  161. }
  162. int llc_conn_ac_clear_remote_busy_if_f_eq_1(struct sock *sk,
  163. struct sk_buff *skb)
  164. {
  165. struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
  166. if (LLC_PDU_IS_RSP(pdu) &&
  167. LLC_PDU_TYPE_IS_I(pdu) &&
  168. LLC_I_PF_IS_1(pdu) && llc_sk(sk)->ack_pf)
  169. llc_conn_ac_clear_remote_busy(sk, skb);
  170. return 0;
  171. }
  172. int llc_conn_ac_stop_rej_tmr_if_data_flag_eq_2(struct sock *sk,
  173. struct sk_buff *skb)
  174. {
  175. struct llc_sock *llc = llc_sk(sk);
  176. if (llc->data_flag == 2)
  177. del_timer(&llc->rej_sent_timer.timer);
  178. return 0;
  179. }
  180. int llc_conn_ac_send_disc_cmd_p_set_x(struct sock *sk, struct sk_buff *skb)
  181. {
  182. int rc = -ENOBUFS;
  183. struct llc_sock *llc = llc_sk(sk);
  184. struct sk_buff *nskb = llc_alloc_frame(llc->dev);
  185. if (nskb) {
  186. struct llc_sap *sap = llc->sap;
  187. llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
  188. llc->daddr.lsap, LLC_PDU_CMD);
  189. llc_pdu_init_as_disc_cmd(nskb, 1);
  190. rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
  191. if (rc)
  192. goto free;
  193. llc_conn_send_pdu(sk, nskb);
  194. llc_conn_ac_set_p_flag_1(sk, skb);
  195. }
  196. out:
  197. return rc;
  198. free:
  199. kfree_skb(nskb);
  200. goto out;
  201. }
  202. int llc_conn_ac_send_dm_rsp_f_set_p(struct sock *sk, struct sk_buff *skb)
  203. {
  204. int rc = -ENOBUFS;
  205. struct llc_sock *llc = llc_sk(sk);
  206. struct sk_buff *nskb = llc_alloc_frame(llc->dev);
  207. if (nskb) {
  208. struct llc_sap *sap = llc->sap;
  209. u8 f_bit;
  210. llc_pdu_decode_pf_bit(skb, &f_bit);
  211. llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
  212. llc->daddr.lsap, LLC_PDU_RSP);
  213. llc_pdu_init_as_dm_rsp(nskb, f_bit);
  214. rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
  215. if (rc)
  216. goto free;
  217. llc_conn_send_pdu(sk, nskb);
  218. }
  219. out:
  220. return rc;
  221. free:
  222. kfree_skb(nskb);
  223. goto out;
  224. }
  225. int llc_conn_ac_send_dm_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
  226. {
  227. int rc = -ENOBUFS;
  228. struct llc_sock *llc = llc_sk(sk);
  229. struct sk_buff *nskb = llc_alloc_frame(llc->dev);
  230. if (nskb) {
  231. struct llc_sap *sap = llc->sap;
  232. llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
  233. llc->daddr.lsap, LLC_PDU_RSP);
  234. llc_pdu_init_as_dm_rsp(nskb, 1);
  235. rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
  236. if (rc)
  237. goto free;
  238. llc_conn_send_pdu(sk, nskb);
  239. }
  240. out:
  241. return rc;
  242. free:
  243. kfree_skb(nskb);
  244. goto out;
  245. }
  246. int llc_conn_ac_send_frmr_rsp_f_set_x(struct sock *sk, struct sk_buff *skb)
  247. {
  248. u8 f_bit;
  249. int rc = -ENOBUFS;
  250. struct sk_buff *nskb;
  251. struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
  252. struct llc_sock *llc = llc_sk(sk);
  253. llc->rx_pdu_hdr = *((u32 *)pdu);
  254. if (LLC_PDU_IS_CMD(pdu))
  255. llc_pdu_decode_pf_bit(skb, &f_bit);
  256. else
  257. f_bit = 0;
  258. nskb = llc_alloc_frame(llc->dev);
  259. if (nskb) {
  260. struct llc_sap *sap = llc->sap;
  261. llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
  262. llc->daddr.lsap, LLC_PDU_RSP);
  263. llc_pdu_init_as_frmr_rsp(nskb, pdu, f_bit, llc->vS,
  264. llc->vR, INCORRECT);
  265. rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
  266. if (rc)
  267. goto free;
  268. llc_conn_send_pdu(sk, nskb);
  269. }
  270. out:
  271. return rc;
  272. free:
  273. kfree_skb(nskb);
  274. goto out;
  275. }
  276. int llc_conn_ac_resend_frmr_rsp_f_set_0(struct sock *sk, struct sk_buff *skb)
  277. {
  278. int rc = -ENOBUFS;
  279. struct llc_sock *llc = llc_sk(sk);
  280. struct sk_buff *nskb = llc_alloc_frame(llc->dev);
  281. if (nskb) {
  282. struct llc_sap *sap = llc->sap;
  283. struct llc_pdu_sn *pdu = (struct llc_pdu_sn *)&llc->rx_pdu_hdr;
  284. llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
  285. llc->daddr.lsap, LLC_PDU_RSP);
  286. llc_pdu_init_as_frmr_rsp(nskb, pdu, 0, llc->vS,
  287. llc->vR, INCORRECT);
  288. rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
  289. if (rc)
  290. goto free;
  291. llc_conn_send_pdu(sk, nskb);
  292. }
  293. out:
  294. return rc;
  295. free:
  296. kfree_skb(nskb);
  297. goto out;
  298. }
  299. int llc_conn_ac_resend_frmr_rsp_f_set_p(struct sock *sk, struct sk_buff *skb)
  300. {
  301. u8 f_bit;
  302. int rc = -ENOBUFS;
  303. struct sk_buff *nskb;
  304. struct llc_sock *llc = llc_sk(sk);
  305. llc_pdu_decode_pf_bit(skb, &f_bit);
  306. nskb = llc_alloc_frame(llc->dev);
  307. if (nskb) {
  308. struct llc_sap *sap = llc->sap;
  309. struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
  310. llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
  311. llc->daddr.lsap, LLC_PDU_RSP);
  312. llc_pdu_init_as_frmr_rsp(nskb, pdu, f_bit, llc->vS,
  313. llc->vR, INCORRECT);
  314. rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
  315. if (rc)
  316. goto free;
  317. llc_conn_send_pdu(sk, nskb);
  318. }
  319. out:
  320. return rc;
  321. free:
  322. kfree_skb(nskb);
  323. goto out;
  324. }
  325. int llc_conn_ac_send_i_cmd_p_set_1(struct sock *sk, struct sk_buff *skb)
  326. {
  327. int rc;
  328. struct llc_sock *llc = llc_sk(sk);
  329. struct llc_sap *sap = llc->sap;
  330. llc_pdu_header_init(skb, LLC_PDU_TYPE_I, sap->laddr.lsap,
  331. llc->daddr.lsap, LLC_PDU_CMD);
  332. llc_pdu_init_as_i_cmd(skb, 1, llc->vS, llc->vR);
  333. rc = llc_mac_hdr_init(skb, llc->dev->dev_addr, llc->daddr.mac);
  334. if (!rc) {
  335. llc_conn_send_pdu(sk, skb);
  336. llc_conn_ac_inc_vs_by_1(sk, skb);
  337. }
  338. return rc;
  339. }
  340. static int llc_conn_ac_send_i_cmd_p_set_0(struct sock *sk, struct sk_buff *skb)
  341. {
  342. int rc;
  343. struct llc_sock *llc = llc_sk(sk);
  344. struct llc_sap *sap = llc->sap;
  345. llc_pdu_header_init(skb, LLC_PDU_TYPE_I, sap->laddr.lsap,
  346. llc->daddr.lsap, LLC_PDU_CMD);
  347. llc_pdu_init_as_i_cmd(skb, 0, llc->vS, llc->vR);
  348. rc = llc_mac_hdr_init(skb, llc->dev->dev_addr, llc->daddr.mac);
  349. if (!rc) {
  350. llc_conn_send_pdu(sk, skb);
  351. llc_conn_ac_inc_vs_by_1(sk, skb);
  352. }
  353. return rc;
  354. }
  355. int llc_conn_ac_send_i_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
  356. {
  357. int rc;
  358. struct llc_sock *llc = llc_sk(sk);
  359. struct llc_sap *sap = llc->sap;
  360. llc_pdu_header_init(skb, LLC_PDU_TYPE_I, sap->laddr.lsap,
  361. llc->daddr.lsap, LLC_PDU_CMD);
  362. llc_pdu_init_as_i_cmd(skb, 0, llc->vS, llc->vR);
  363. rc = llc_mac_hdr_init(skb, llc->dev->dev_addr, llc->daddr.mac);
  364. if (!rc) {
  365. llc_conn_send_pdu(sk, skb);
  366. llc_conn_ac_inc_vs_by_1(sk, skb);
  367. }
  368. return 0;
  369. }
  370. int llc_conn_ac_resend_i_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
  371. {
  372. struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
  373. u8 nr = LLC_I_GET_NR(pdu);
  374. llc_conn_resend_i_pdu_as_cmd(sk, nr, 0);
  375. return 0;
  376. }
  377. int llc_conn_ac_resend_i_xxx_x_set_0_or_send_rr(struct sock *sk,
  378. struct sk_buff *skb)
  379. {
  380. u8 nr;
  381. struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
  382. int rc = -ENOBUFS;
  383. struct llc_sock *llc = llc_sk(sk);
  384. struct sk_buff *nskb = llc_alloc_frame(llc->dev);
  385. if (nskb) {
  386. struct llc_sap *sap = llc->sap;
  387. llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
  388. llc->daddr.lsap, LLC_PDU_RSP);
  389. llc_pdu_init_as_rr_rsp(nskb, 0, llc->vR);
  390. rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
  391. if (!rc)
  392. llc_conn_send_pdu(sk, nskb);
  393. else
  394. kfree_skb(skb);
  395. }
  396. if (rc) {
  397. nr = LLC_I_GET_NR(pdu);
  398. rc = 0;
  399. llc_conn_resend_i_pdu_as_cmd(sk, nr, 0);
  400. }
  401. return rc;
  402. }
  403. int llc_conn_ac_resend_i_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
  404. {
  405. struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
  406. u8 nr = LLC_I_GET_NR(pdu);
  407. llc_conn_resend_i_pdu_as_rsp(sk, nr, 1);
  408. return 0;
  409. }
  410. int llc_conn_ac_send_rej_cmd_p_set_1(struct sock *sk, struct sk_buff *skb)
  411. {
  412. int rc = -ENOBUFS;
  413. struct llc_sock *llc = llc_sk(sk);
  414. struct sk_buff *nskb = llc_alloc_frame(llc->dev);
  415. if (nskb) {
  416. struct llc_sap *sap = llc->sap;
  417. llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
  418. llc->daddr.lsap, LLC_PDU_CMD);
  419. llc_pdu_init_as_rej_cmd(nskb, 1, llc->vR);
  420. rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
  421. if (rc)
  422. goto free;
  423. llc_conn_send_pdu(sk, nskb);
  424. }
  425. out:
  426. return rc;
  427. free:
  428. kfree_skb(nskb);
  429. goto out;
  430. }
  431. int llc_conn_ac_send_rej_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
  432. {
  433. int rc = -ENOBUFS;
  434. struct llc_sock *llc = llc_sk(sk);
  435. struct sk_buff *nskb = llc_alloc_frame(llc->dev);
  436. if (nskb) {
  437. struct llc_sap *sap = llc->sap;
  438. llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
  439. llc->daddr.lsap, LLC_PDU_RSP);
  440. llc_pdu_init_as_rej_rsp(nskb, 1, llc->vR);
  441. rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
  442. if (rc)
  443. goto free;
  444. llc_conn_send_pdu(sk, nskb);
  445. }
  446. out:
  447. return rc;
  448. free:
  449. kfree_skb(nskb);
  450. goto out;
  451. }
  452. int llc_conn_ac_send_rej_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
  453. {
  454. int rc = -ENOBUFS;
  455. struct llc_sock *llc = llc_sk(sk);
  456. struct sk_buff *nskb = llc_alloc_frame(llc->dev);
  457. if (nskb) {
  458. struct llc_sap *sap = llc->sap;
  459. llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
  460. llc->daddr.lsap, LLC_PDU_RSP);
  461. llc_pdu_init_as_rej_rsp(nskb, 0, llc->vR);
  462. rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
  463. if (rc)
  464. goto free;
  465. llc_conn_send_pdu(sk, nskb);
  466. }
  467. out:
  468. return rc;
  469. free:
  470. kfree_skb(nskb);
  471. goto out;
  472. }
  473. int llc_conn_ac_send_rnr_cmd_p_set_1(struct sock *sk, struct sk_buff *skb)
  474. {
  475. int rc = -ENOBUFS;
  476. struct llc_sock *llc = llc_sk(sk);
  477. struct sk_buff *nskb = llc_alloc_frame(llc->dev);
  478. if (nskb) {
  479. struct llc_sap *sap = llc->sap;
  480. llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
  481. llc->daddr.lsap, LLC_PDU_CMD);
  482. llc_pdu_init_as_rnr_cmd(nskb, 1, llc->vR);
  483. rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
  484. if (rc)
  485. goto free;
  486. llc_conn_send_pdu(sk, nskb);
  487. }
  488. out:
  489. return rc;
  490. free:
  491. kfree_skb(nskb);
  492. goto out;
  493. }
  494. int llc_conn_ac_send_rnr_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
  495. {
  496. int rc = -ENOBUFS;
  497. struct llc_sock *llc = llc_sk(sk);
  498. struct sk_buff *nskb = llc_alloc_frame(llc->dev);
  499. if (nskb) {
  500. struct llc_sap *sap = llc->sap;
  501. llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
  502. llc->daddr.lsap, LLC_PDU_RSP);
  503. llc_pdu_init_as_rnr_rsp(nskb, 1, llc->vR);
  504. rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
  505. if (rc)
  506. goto free;
  507. llc_conn_send_pdu(sk, nskb);
  508. }
  509. out:
  510. return rc;
  511. free:
  512. kfree_skb(nskb);
  513. goto out;
  514. }
  515. int llc_conn_ac_send_rnr_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
  516. {
  517. int rc = -ENOBUFS;
  518. struct llc_sock *llc = llc_sk(sk);
  519. struct sk_buff *nskb = llc_alloc_frame(llc->dev);
  520. if (nskb) {
  521. struct llc_sap *sap = llc->sap;
  522. llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
  523. llc->daddr.lsap, LLC_PDU_RSP);
  524. llc_pdu_init_as_rnr_rsp(nskb, 0, llc->vR);
  525. rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
  526. if (rc)
  527. goto free;
  528. llc_conn_send_pdu(sk, nskb);
  529. }
  530. out:
  531. return rc;
  532. free:
  533. kfree_skb(nskb);
  534. goto out;
  535. }
  536. int llc_conn_ac_set_remote_busy(struct sock *sk, struct sk_buff *skb)
  537. {
  538. struct llc_sock *llc = llc_sk(sk);
  539. if (!llc->remote_busy_flag) {
  540. llc->remote_busy_flag = 1;
  541. mod_timer(&llc->busy_state_timer.timer,
  542. jiffies + llc->busy_state_timer.expire * HZ);
  543. }
  544. return 0;
  545. }
  546. int llc_conn_ac_opt_send_rnr_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
  547. {
  548. int rc = -ENOBUFS;
  549. struct llc_sock *llc = llc_sk(sk);
  550. struct sk_buff *nskb = llc_alloc_frame(llc->dev);
  551. if (nskb) {
  552. struct llc_sap *sap = llc->sap;
  553. llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
  554. llc->daddr.lsap, LLC_PDU_RSP);
  555. llc_pdu_init_as_rnr_rsp(nskb, 0, llc->vR);
  556. rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
  557. if (rc)
  558. goto free;
  559. llc_conn_send_pdu(sk, nskb);
  560. }
  561. out:
  562. return rc;
  563. free:
  564. kfree_skb(nskb);
  565. goto out;
  566. }
  567. int llc_conn_ac_send_rr_cmd_p_set_1(struct sock *sk, struct sk_buff *skb)
  568. {
  569. int rc = -ENOBUFS;
  570. struct llc_sock *llc = llc_sk(sk);
  571. struct sk_buff *nskb = llc_alloc_frame(llc->dev);
  572. if (nskb) {
  573. struct llc_sap *sap = llc->sap;
  574. llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
  575. llc->daddr.lsap, LLC_PDU_CMD);
  576. llc_pdu_init_as_rr_cmd(nskb, 1, llc->vR);
  577. rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
  578. if (rc)
  579. goto free;
  580. llc_conn_send_pdu(sk, nskb);
  581. }
  582. out:
  583. return rc;
  584. free:
  585. kfree_skb(nskb);
  586. goto out;
  587. }
  588. int llc_conn_ac_send_rr_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
  589. {
  590. int rc = -ENOBUFS;
  591. struct llc_sock *llc = llc_sk(sk);
  592. struct sk_buff *nskb = llc_alloc_frame(llc->dev);
  593. if (nskb) {
  594. struct llc_sap *sap = llc->sap;
  595. u8 f_bit = 1;
  596. llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
  597. llc->daddr.lsap, LLC_PDU_RSP);
  598. llc_pdu_init_as_rr_rsp(nskb, f_bit, llc->vR);
  599. rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
  600. if (rc)
  601. goto free;
  602. llc_conn_send_pdu(sk, nskb);
  603. }
  604. out:
  605. return rc;
  606. free:
  607. kfree_skb(nskb);
  608. goto out;
  609. }
  610. int llc_conn_ac_send_ack_rsp_f_set_1(struct sock *sk, struct sk_buff *skb)
  611. {
  612. int rc = -ENOBUFS;
  613. struct llc_sock *llc = llc_sk(sk);
  614. struct sk_buff *nskb = llc_alloc_frame(llc->dev);
  615. if (nskb) {
  616. struct llc_sap *sap = llc->sap;
  617. llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
  618. llc->daddr.lsap, LLC_PDU_RSP);
  619. llc_pdu_init_as_rr_rsp(nskb, 1, llc->vR);
  620. rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
  621. if (rc)
  622. goto free;
  623. llc_conn_send_pdu(sk, nskb);
  624. }
  625. out:
  626. return rc;
  627. free:
  628. kfree_skb(nskb);
  629. goto out;
  630. }
  631. int llc_conn_ac_send_rr_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
  632. {
  633. int rc = -ENOBUFS;
  634. struct llc_sock *llc = llc_sk(sk);
  635. struct sk_buff *nskb = llc_alloc_frame(llc->dev);
  636. if (nskb) {
  637. struct llc_sap *sap = llc->sap;
  638. llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
  639. llc->daddr.lsap, LLC_PDU_RSP);
  640. llc_pdu_init_as_rr_rsp(nskb, 0, llc->vR);
  641. rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
  642. if (rc)
  643. goto free;
  644. llc_conn_send_pdu(sk, nskb);
  645. }
  646. out:
  647. return rc;
  648. free:
  649. kfree_skb(nskb);
  650. goto out;
  651. }
  652. int llc_conn_ac_send_ack_xxx_x_set_0(struct sock *sk, struct sk_buff *skb)
  653. {
  654. int rc = -ENOBUFS;
  655. struct llc_sock *llc = llc_sk(sk);
  656. struct sk_buff *nskb = llc_alloc_frame(llc->dev);
  657. if (nskb) {
  658. struct llc_sap *sap = llc->sap;
  659. llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
  660. llc->daddr.lsap, LLC_PDU_RSP);
  661. llc_pdu_init_as_rr_rsp(nskb, 0, llc->vR);
  662. rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
  663. if (rc)
  664. goto free;
  665. llc_conn_send_pdu(sk, nskb);
  666. }
  667. out:
  668. return rc;
  669. free:
  670. kfree_skb(nskb);
  671. goto out;
  672. }
  673. void llc_conn_set_p_flag(struct sock *sk, u8 value)
  674. {
  675. int state_changed = llc_sk(sk)->p_flag && !value;
  676. llc_sk(sk)->p_flag = value;
  677. if (state_changed)
  678. sk->sk_state_change(sk);
  679. }
  680. int llc_conn_ac_send_sabme_cmd_p_set_x(struct sock *sk, struct sk_buff *skb)
  681. {
  682. int rc = -ENOBUFS;
  683. struct llc_sock *llc = llc_sk(sk);
  684. struct sk_buff *nskb = llc_alloc_frame(llc->dev);
  685. if (nskb) {
  686. struct llc_sap *sap = llc->sap;
  687. u8 *dmac = llc->daddr.mac;
  688. if (llc->dev->flags & IFF_LOOPBACK)
  689. dmac = llc->dev->dev_addr;
  690. llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
  691. llc->daddr.lsap, LLC_PDU_CMD);
  692. llc_pdu_init_as_sabme_cmd(nskb, 1);
  693. rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, dmac);
  694. if (rc)
  695. goto free;
  696. llc_conn_send_pdu(sk, nskb);
  697. llc_conn_set_p_flag(sk, 1);
  698. }
  699. out:
  700. return rc;
  701. free:
  702. kfree_skb(nskb);
  703. goto out;
  704. }
  705. int llc_conn_ac_send_ua_rsp_f_set_p(struct sock *sk, struct sk_buff *skb)
  706. {
  707. u8 f_bit;
  708. int rc = -ENOBUFS;
  709. struct llc_sock *llc = llc_sk(sk);
  710. struct sk_buff *nskb = llc_alloc_frame(llc->dev);
  711. llc_pdu_decode_pf_bit(skb, &f_bit);
  712. if (nskb) {
  713. struct llc_sap *sap = llc->sap;
  714. nskb->dev = llc->dev;
  715. llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, sap->laddr.lsap,
  716. llc->daddr.lsap, LLC_PDU_RSP);
  717. llc_pdu_init_as_ua_rsp(nskb, f_bit);
  718. rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
  719. if (rc)
  720. goto free;
  721. llc_conn_send_pdu(sk, nskb);
  722. }
  723. out:
  724. return rc;
  725. free:
  726. kfree_skb(nskb);
  727. goto out;
  728. }
  729. int llc_conn_ac_set_s_flag_0(struct sock *sk, struct sk_buff *skb)
  730. {
  731. llc_sk(sk)->s_flag = 0;
  732. return 0;
  733. }
  734. int llc_conn_ac_set_s_flag_1(struct sock *sk, struct sk_buff *skb)
  735. {
  736. llc_sk(sk)->s_flag = 1;
  737. return 0;
  738. }
  739. int llc_conn_ac_start_p_timer(struct sock *sk, struct sk_buff *skb)
  740. {
  741. struct llc_sock *llc = llc_sk(sk);
  742. llc_conn_set_p_flag(sk, 1);
  743. mod_timer(&llc->pf_cycle_timer.timer,
  744. jiffies + llc->pf_cycle_timer.expire * HZ);
  745. return 0;
  746. }
  747. /**
  748. * llc_conn_ac_send_ack_if_needed - check if ack is needed
  749. * @sk: current connection structure
  750. * @skb: current event
  751. *
  752. * Checks number of received PDUs which have not been acknowledged, yet,
  753. * If number of them reaches to "npta"(Number of PDUs To Acknowledge) then
  754. * sends an RR response as acknowledgement for them. Returns 0 for
  755. * success, 1 otherwise.
  756. */
  757. int llc_conn_ac_send_ack_if_needed(struct sock *sk, struct sk_buff *skb)
  758. {
  759. u8 pf_bit;
  760. struct llc_sock *llc = llc_sk(sk);
  761. llc_pdu_decode_pf_bit(skb, &pf_bit);
  762. llc->ack_pf |= pf_bit & 1;
  763. if (!llc->ack_must_be_send) {
  764. llc->first_pdu_Ns = llc->vR;
  765. llc->ack_must_be_send = 1;
  766. llc->ack_pf = pf_bit & 1;
  767. }
  768. if (((llc->vR - llc->first_pdu_Ns + 129) % 128) >= llc->npta) {
  769. llc_conn_ac_send_rr_rsp_f_set_ackpf(sk, skb);
  770. llc->ack_must_be_send = 0;
  771. llc->ack_pf = 0;
  772. llc_conn_ac_inc_npta_value(sk, skb);
  773. }
  774. return 0;
  775. }
  776. /**
  777. * llc_conn_ac_rst_sendack_flag - resets ack_must_be_send flag
  778. * @sk: current connection structure
  779. * @skb: current event
  780. *
  781. * This action resets ack_must_be_send flag of given connection, this flag
  782. * indicates if there is any PDU which has not been acknowledged yet.
  783. * Returns 0 for success, 1 otherwise.
  784. */
  785. int llc_conn_ac_rst_sendack_flag(struct sock *sk, struct sk_buff *skb)
  786. {
  787. llc_sk(sk)->ack_must_be_send = llc_sk(sk)->ack_pf = 0;
  788. return 0;
  789. }
  790. /**
  791. * llc_conn_ac_send_i_rsp_f_set_ackpf - acknowledge received PDUs
  792. * @sk: current connection structure
  793. * @skb: current event
  794. *
  795. * Sends an I response PDU with f-bit set to ack_pf flag as acknowledge to
  796. * all received PDUs which have not been acknowledged, yet. ack_pf flag is
  797. * set to one if one PDU with p-bit set to one is received. Returns 0 for
  798. * success, 1 otherwise.
  799. */
  800. static int llc_conn_ac_send_i_rsp_f_set_ackpf(struct sock *sk,
  801. struct sk_buff *skb)
  802. {
  803. int rc;
  804. struct llc_sock *llc = llc_sk(sk);
  805. struct llc_sap *sap = llc->sap;
  806. llc_pdu_header_init(skb, LLC_PDU_TYPE_I, sap->laddr.lsap,
  807. llc->daddr.lsap, LLC_PDU_RSP);
  808. llc_pdu_init_as_i_cmd(skb, llc->ack_pf, llc->vS, llc->vR);
  809. rc = llc_mac_hdr_init(skb, llc->dev->dev_addr, llc->daddr.mac);
  810. if (!rc) {
  811. llc_conn_send_pdu(sk, skb);
  812. llc_conn_ac_inc_vs_by_1(sk, skb);
  813. }
  814. return rc;
  815. }
  816. /**
  817. * llc_conn_ac_send_i_as_ack - sends an I-format PDU to acknowledge rx PDUs
  818. * @sk: current connection structure.
  819. * @skb: current event.
  820. *
  821. * This action sends an I-format PDU as acknowledge to received PDUs which
  822. * have not been acknowledged, yet, if there is any. By using of this
  823. * action number of acknowledgements decreases, this technic is called
  824. * piggy backing. Returns 0 for success, 1 otherwise.
  825. */
  826. int llc_conn_ac_send_i_as_ack(struct sock *sk, struct sk_buff *skb)
  827. {
  828. struct llc_sock *llc = llc_sk(sk);
  829. if (llc->ack_must_be_send) {
  830. llc_conn_ac_send_i_rsp_f_set_ackpf(sk, skb);
  831. llc->ack_must_be_send = 0 ;
  832. llc->ack_pf = 0;
  833. } else
  834. llc_conn_ac_send_i_cmd_p_set_0(sk, skb);
  835. return 0;
  836. }
  837. /**
  838. * llc_conn_ac_send_rr_rsp_f_set_ackpf - ack all rx PDUs not yet acked
  839. * @sk: current connection structure.
  840. * @skb: current event.
  841. *
  842. * This action sends an RR response with f-bit set to ack_pf flag as
  843. * acknowledge to all received PDUs which have not been acknowledged, yet,
  844. * if there is any. ack_pf flag indicates if a PDU has been received with
  845. * p-bit set to one. Returns 0 for success, 1 otherwise.
  846. */
  847. static int llc_conn_ac_send_rr_rsp_f_set_ackpf(struct sock *sk,
  848. struct sk_buff *skb)
  849. {
  850. int rc = -ENOBUFS;
  851. struct llc_sock *llc = llc_sk(sk);
  852. struct sk_buff *nskb = llc_alloc_frame(llc->dev);
  853. if (nskb) {
  854. struct llc_sap *sap = llc->sap;
  855. llc_pdu_header_init(nskb, LLC_PDU_TYPE_S, sap->laddr.lsap,
  856. llc->daddr.lsap, LLC_PDU_RSP);
  857. llc_pdu_init_as_rr_rsp(nskb, llc->ack_pf, llc->vR);
  858. rc = llc_mac_hdr_init(nskb, llc->dev->dev_addr, llc->daddr.mac);
  859. if (rc)
  860. goto free;
  861. llc_conn_send_pdu(sk, nskb);
  862. }
  863. out:
  864. return rc;
  865. free:
  866. kfree_skb(nskb);
  867. goto out;
  868. }
  869. /**
  870. * llc_conn_ac_inc_npta_value - tries to make value of npta greater
  871. * @sk: current connection structure.
  872. * @skb: current event.
  873. *
  874. * After "inc_cntr" times calling of this action, "npta" increase by one.
  875. * this action tries to make vale of "npta" greater as possible; number of
  876. * acknowledgements decreases by increasing of "npta". Returns 0 for
  877. * success, 1 otherwise.
  878. */
  879. static int llc_conn_ac_inc_npta_value(struct sock *sk, struct sk_buff *skb)
  880. {
  881. struct llc_sock *llc = llc_sk(sk);
  882. if (!llc->inc_cntr) {
  883. llc->dec_step = 0;
  884. llc->dec_cntr = llc->inc_cntr = 2;
  885. ++llc->npta;
  886. if (llc->npta > 127)
  887. llc->npta = 127 ;
  888. } else
  889. --llc->inc_cntr;
  890. return 0;
  891. }
  892. /**
  893. * llc_conn_ac_adjust_npta_by_rr - decreases "npta" by one
  894. * @sk: current connection structure.
  895. * @skb: current event.
  896. *
  897. * After receiving "dec_cntr" times RR command, this action decreases
  898. * "npta" by one. Returns 0 for success, 1 otherwise.
  899. */
  900. int llc_conn_ac_adjust_npta_by_rr(struct sock *sk, struct sk_buff *skb)
  901. {
  902. struct llc_sock *llc = llc_sk(sk);
  903. if (!llc->connect_step && !llc->remote_busy_flag) {
  904. if (!llc->dec_step) {
  905. if (!llc->dec_cntr) {
  906. llc->inc_cntr = llc->dec_cntr = 2;
  907. if (llc->npta > 0)
  908. llc->npta = llc->npta - 1;
  909. } else
  910. llc->dec_cntr -=1;
  911. }
  912. } else
  913. llc->connect_step = 0 ;
  914. return 0;
  915. }
  916. /**
  917. * llc_conn_ac_adjust_npta_by_rnr - decreases "npta" by one
  918. * @sk: current connection structure.
  919. * @skb: current event.
  920. *
  921. * After receiving "dec_cntr" times RNR command, this action decreases
  922. * "npta" by one. Returns 0 for success, 1 otherwise.
  923. */
  924. int llc_conn_ac_adjust_npta_by_rnr(struct sock *sk, struct sk_buff *skb)
  925. {
  926. struct llc_sock *llc = llc_sk(sk);
  927. if (llc->remote_busy_flag)
  928. if (!llc->dec_step) {
  929. if (!llc->dec_cntr) {
  930. llc->inc_cntr = llc->dec_cntr = 2;
  931. if (llc->npta > 0)
  932. --llc->npta;
  933. } else
  934. --llc->dec_cntr;
  935. }
  936. return 0;
  937. }
  938. /**
  939. * llc_conn_ac_dec_tx_win_size - decreases tx window size
  940. * @sk: current connection structure.
  941. * @skb: current event.
  942. *
  943. * After receiving of a REJ command or response, transmit window size is
  944. * decreased by number of PDUs which are outstanding yet. Returns 0 for
  945. * success, 1 otherwise.
  946. */
  947. int llc_conn_ac_dec_tx_win_size(struct sock *sk, struct sk_buff *skb)
  948. {
  949. struct llc_sock *llc = llc_sk(sk);
  950. u8 unacked_pdu = skb_queue_len(&llc->pdu_unack_q);
  951. llc->k -= unacked_pdu;
  952. if (llc->k < 2)
  953. llc->k = 2;
  954. return 0;
  955. }
  956. /**
  957. * llc_conn_ac_inc_tx_win_size - tx window size is inc by 1
  958. * @sk: current connection structure.
  959. * @skb: current event.
  960. *
  961. * After receiving an RR response with f-bit set to one, transmit window
  962. * size is increased by one. Returns 0 for success, 1 otherwise.
  963. */
  964. int llc_conn_ac_inc_tx_win_size(struct sock *sk, struct sk_buff *skb)
  965. {
  966. struct llc_sock *llc = llc_sk(sk);
  967. llc->k += 1;
  968. if (llc->k > 128)
  969. llc->k = 128 ;
  970. return 0;
  971. }
  972. int llc_conn_ac_stop_all_timers(struct sock *sk, struct sk_buff *skb)
  973. {
  974. struct llc_sock *llc = llc_sk(sk);
  975. del_timer(&llc->pf_cycle_timer.timer);
  976. del_timer(&llc->ack_timer.timer);
  977. del_timer(&llc->rej_sent_timer.timer);
  978. del_timer(&llc->busy_state_timer.timer);
  979. llc->ack_must_be_send = 0;
  980. llc->ack_pf = 0;
  981. return 0;
  982. }
  983. int llc_conn_ac_stop_other_timers(struct sock *sk, struct sk_buff *skb)
  984. {
  985. struct llc_sock *llc = llc_sk(sk);
  986. del_timer(&llc->rej_sent_timer.timer);
  987. del_timer(&llc->pf_cycle_timer.timer);
  988. del_timer(&llc->busy_state_timer.timer);
  989. llc->ack_must_be_send = 0;
  990. llc->ack_pf = 0;
  991. return 0;
  992. }
  993. int llc_conn_ac_start_ack_timer(struct sock *sk, struct sk_buff *skb)
  994. {
  995. struct llc_sock *llc = llc_sk(sk);
  996. mod_timer(&llc->ack_timer.timer, jiffies + llc->ack_timer.expire * HZ);
  997. return 0;
  998. }
  999. int llc_conn_ac_start_rej_timer(struct sock *sk, struct sk_buff *skb)
  1000. {
  1001. struct llc_sock *llc = llc_sk(sk);
  1002. mod_timer(&llc->rej_sent_timer.timer,
  1003. jiffies + llc->rej_sent_timer.expire * HZ);
  1004. return 0;
  1005. }
  1006. int llc_conn_ac_start_ack_tmr_if_not_running(struct sock *sk,
  1007. struct sk_buff *skb)
  1008. {
  1009. struct llc_sock *llc = llc_sk(sk);
  1010. if (!timer_pending(&llc->ack_timer.timer))
  1011. mod_timer(&llc->ack_timer.timer,
  1012. jiffies + llc->ack_timer.expire * HZ);
  1013. return 0;
  1014. }
  1015. int llc_conn_ac_stop_ack_timer(struct sock *sk, struct sk_buff *skb)
  1016. {
  1017. del_timer(&llc_sk(sk)->ack_timer.timer);
  1018. return 0;
  1019. }
  1020. int llc_conn_ac_stop_p_timer(struct sock *sk, struct sk_buff *skb)
  1021. {
  1022. struct llc_sock *llc = llc_sk(sk);
  1023. del_timer(&llc->pf_cycle_timer.timer);
  1024. llc_conn_set_p_flag(sk, 0);
  1025. return 0;
  1026. }
  1027. int llc_conn_ac_stop_rej_timer(struct sock *sk, struct sk_buff *skb)
  1028. {
  1029. del_timer(&llc_sk(sk)->rej_sent_timer.timer);
  1030. return 0;
  1031. }
  1032. int llc_conn_ac_upd_nr_received(struct sock *sk, struct sk_buff *skb)
  1033. {
  1034. int acked;
  1035. u16 unacked = 0;
  1036. struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
  1037. struct llc_sock *llc = llc_sk(sk);
  1038. llc->last_nr = PDU_SUPV_GET_Nr(pdu);
  1039. acked = llc_conn_remove_acked_pdus(sk, llc->last_nr, &unacked);
  1040. /* On loopback we don't queue I frames in unack_pdu_q queue. */
  1041. if (acked > 0 || (llc->dev->flags & IFF_LOOPBACK)) {
  1042. llc->retry_count = 0;
  1043. del_timer(&llc->ack_timer.timer);
  1044. if (llc->failed_data_req) {
  1045. /* already, we did not accept data from upper layer
  1046. * (tx_window full or unacceptable state). Now, we
  1047. * can send data and must inform to upper layer.
  1048. */
  1049. llc->failed_data_req = 0;
  1050. llc_conn_ac_data_confirm(sk, skb);
  1051. }
  1052. if (unacked)
  1053. mod_timer(&llc->ack_timer.timer,
  1054. jiffies + llc->ack_timer.expire * HZ);
  1055. } else if (llc->failed_data_req) {
  1056. u8 f_bit;
  1057. llc_pdu_decode_pf_bit(skb, &f_bit);
  1058. if (f_bit == 1) {
  1059. llc->failed_data_req = 0;
  1060. llc_conn_ac_data_confirm(sk, skb);
  1061. }
  1062. }
  1063. return 0;
  1064. }
  1065. int llc_conn_ac_upd_p_flag(struct sock *sk, struct sk_buff *skb)
  1066. {
  1067. struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
  1068. if (LLC_PDU_IS_RSP(pdu)) {
  1069. u8 f_bit;
  1070. llc_pdu_decode_pf_bit(skb, &f_bit);
  1071. if (f_bit) {
  1072. llc_conn_set_p_flag(sk, 0);
  1073. llc_conn_ac_stop_p_timer(sk, skb);
  1074. }
  1075. }
  1076. return 0;
  1077. }
  1078. int llc_conn_ac_set_data_flag_2(struct sock *sk, struct sk_buff *skb)
  1079. {
  1080. llc_sk(sk)->data_flag = 2;
  1081. return 0;
  1082. }
  1083. int llc_conn_ac_set_data_flag_0(struct sock *sk, struct sk_buff *skb)
  1084. {
  1085. llc_sk(sk)->data_flag = 0;
  1086. return 0;
  1087. }
  1088. int llc_conn_ac_set_data_flag_1(struct sock *sk, struct sk_buff *skb)
  1089. {
  1090. llc_sk(sk)->data_flag = 1;
  1091. return 0;
  1092. }
  1093. int llc_conn_ac_set_data_flag_1_if_data_flag_eq_0(struct sock *sk,
  1094. struct sk_buff *skb)
  1095. {
  1096. if (!llc_sk(sk)->data_flag)
  1097. llc_sk(sk)->data_flag = 1;
  1098. return 0;
  1099. }
  1100. int llc_conn_ac_set_p_flag_0(struct sock *sk, struct sk_buff *skb)
  1101. {
  1102. llc_conn_set_p_flag(sk, 0);
  1103. return 0;
  1104. }
  1105. static int llc_conn_ac_set_p_flag_1(struct sock *sk, struct sk_buff *skb)
  1106. {
  1107. llc_conn_set_p_flag(sk, 1);
  1108. return 0;
  1109. }
  1110. int llc_conn_ac_set_remote_busy_0(struct sock *sk, struct sk_buff *skb)
  1111. {
  1112. llc_sk(sk)->remote_busy_flag = 0;
  1113. return 0;
  1114. }
  1115. int llc_conn_ac_set_cause_flag_0(struct sock *sk, struct sk_buff *skb)
  1116. {
  1117. llc_sk(sk)->cause_flag = 0;
  1118. return 0;
  1119. }
  1120. int llc_conn_ac_set_cause_flag_1(struct sock *sk, struct sk_buff *skb)
  1121. {
  1122. llc_sk(sk)->cause_flag = 1;
  1123. return 0;
  1124. }
  1125. int llc_conn_ac_set_retry_cnt_0(struct sock *sk, struct sk_buff *skb)
  1126. {
  1127. llc_sk(sk)->retry_count = 0;
  1128. return 0;
  1129. }
  1130. int llc_conn_ac_inc_retry_cnt_by_1(struct sock *sk, struct sk_buff *skb)
  1131. {
  1132. llc_sk(sk)->retry_count++;
  1133. return 0;
  1134. }
  1135. int llc_conn_ac_set_vr_0(struct sock *sk, struct sk_buff *skb)
  1136. {
  1137. llc_sk(sk)->vR = 0;
  1138. return 0;
  1139. }
  1140. int llc_conn_ac_inc_vr_by_1(struct sock *sk, struct sk_buff *skb)
  1141. {
  1142. llc_sk(sk)->vR = PDU_GET_NEXT_Vr(llc_sk(sk)->vR);
  1143. return 0;
  1144. }
  1145. int llc_conn_ac_set_vs_0(struct sock *sk, struct sk_buff *skb)
  1146. {
  1147. llc_sk(sk)->vS = 0;
  1148. return 0;
  1149. }
  1150. int llc_conn_ac_set_vs_nr(struct sock *sk, struct sk_buff *skb)
  1151. {
  1152. llc_sk(sk)->vS = llc_sk(sk)->last_nr;
  1153. return 0;
  1154. }
  1155. int llc_conn_ac_inc_vs_by_1(struct sock *sk, struct sk_buff *skb)
  1156. {
  1157. llc_sk(sk)->vS = (llc_sk(sk)->vS + 1) % 128;
  1158. return 0;
  1159. }
  1160. static void llc_conn_tmr_common_cb(unsigned long timeout_data, u8 type)
  1161. {
  1162. struct sock *sk = (struct sock *)timeout_data;
  1163. struct sk_buff *skb = alloc_skb(0, GFP_ATOMIC);
  1164. bh_lock_sock(sk);
  1165. if (skb) {
  1166. struct llc_conn_state_ev *ev = llc_conn_ev(skb);
  1167. skb->sk = sk;
  1168. ev->type = type;
  1169. llc_process_tmr_ev(sk, skb);
  1170. }
  1171. bh_unlock_sock(sk);
  1172. }
  1173. void llc_conn_pf_cycle_tmr_cb(unsigned long timeout_data)
  1174. {
  1175. llc_conn_tmr_common_cb(timeout_data, LLC_CONN_EV_TYPE_P_TMR);
  1176. }
  1177. void llc_conn_busy_tmr_cb(unsigned long timeout_data)
  1178. {
  1179. llc_conn_tmr_common_cb(timeout_data, LLC_CONN_EV_TYPE_BUSY_TMR);
  1180. }
  1181. void llc_conn_ack_tmr_cb(unsigned long timeout_data)
  1182. {
  1183. llc_conn_tmr_common_cb(timeout_data, LLC_CONN_EV_TYPE_ACK_TMR);
  1184. }
  1185. void llc_conn_rej_tmr_cb(unsigned long timeout_data)
  1186. {
  1187. llc_conn_tmr_common_cb(timeout_data, LLC_CONN_EV_TYPE_REJ_TMR);
  1188. }
  1189. int llc_conn_ac_rst_vs(struct sock *sk, struct sk_buff *skb)
  1190. {
  1191. llc_sk(sk)->X = llc_sk(sk)->vS;
  1192. llc_conn_ac_set_vs_nr(sk, skb);
  1193. return 0;
  1194. }
  1195. int llc_conn_ac_upd_vs(struct sock *sk, struct sk_buff *skb)
  1196. {
  1197. struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
  1198. u8 nr = PDU_SUPV_GET_Nr(pdu);
  1199. if (llc_circular_between(llc_sk(sk)->vS, nr, llc_sk(sk)->X))
  1200. llc_conn_ac_set_vs_nr(sk, skb);
  1201. return 0;
  1202. }
  1203. /*
  1204. * Non-standard actions; these not contained in IEEE specification; for
  1205. * our own usage
  1206. */
  1207. /**
  1208. * llc_conn_disc - removes connection from SAP list and frees it
  1209. * @sk: closed connection
  1210. * @skb: occurred event
  1211. */
  1212. int llc_conn_disc(struct sock *sk, struct sk_buff *skb)
  1213. {
  1214. /* FIXME: this thing seems to want to die */
  1215. return 0;
  1216. }
  1217. /**
  1218. * llc_conn_reset - resets connection
  1219. * @sk : reseting connection.
  1220. * @skb: occurred event.
  1221. *
  1222. * Stop all timers, empty all queues and reset all flags.
  1223. */
  1224. int llc_conn_reset(struct sock *sk, struct sk_buff *skb)
  1225. {
  1226. llc_sk_reset(sk);
  1227. return 0;
  1228. }
  1229. /**
  1230. * llc_circular_between - designates that b is between a and c or not
  1231. * @a: lower bound
  1232. * @b: element to see if is between a and b
  1233. * @c: upper bound
  1234. *
  1235. * This function designates that b is between a and c or not (for example,
  1236. * 0 is between 127 and 1). Returns 1 if b is between a and c, 0
  1237. * otherwise.
  1238. */
  1239. u8 llc_circular_between(u8 a, u8 b, u8 c)
  1240. {
  1241. b = b - a;
  1242. c = c - a;
  1243. return b <= c;
  1244. }
  1245. /**
  1246. * llc_process_tmr_ev - timer backend
  1247. * @sk: active connection
  1248. * @skb: occurred event
  1249. *
  1250. * This function is called from timer callback functions. When connection
  1251. * is busy (during sending a data frame) timer expiration event must be
  1252. * queued. Otherwise this event can be sent to connection state machine.
  1253. * Queued events will process by llc_backlog_rcv function after sending
  1254. * data frame.
  1255. */
  1256. static void llc_process_tmr_ev(struct sock *sk, struct sk_buff *skb)
  1257. {
  1258. if (llc_sk(sk)->state == LLC_CONN_OUT_OF_SVC) {
  1259. printk(KERN_WARNING "%s: timer called on closed connection\n",
  1260. __FUNCTION__);
  1261. kfree_skb(skb);
  1262. } else {
  1263. if (!sock_owned_by_user(sk))
  1264. llc_conn_state_process(sk, skb);
  1265. else {
  1266. llc_set_backlog_type(skb, LLC_EVENT);
  1267. sk_add_backlog(sk, skb);
  1268. }
  1269. }
  1270. }