stream.c 29 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186
  1. /* SCTP kernel implementation
  2. * (C) Copyright IBM Corp. 2001, 2004
  3. * Copyright (c) 1999-2000 Cisco, Inc.
  4. * Copyright (c) 1999-2001 Motorola, Inc.
  5. * Copyright (c) 2001 Intel Corp.
  6. *
  7. * This file is part of the SCTP kernel implementation
  8. *
  9. * This file contains sctp stream maniuplation primitives and helpers.
  10. *
  11. * This SCTP implementation is free software;
  12. * you can redistribute it and/or modify it under the terms of
  13. * the GNU General Public License as published by
  14. * the Free Software Foundation; either version 2, or (at your option)
  15. * any later version.
  16. *
  17. * This SCTP implementation is distributed in the hope that it
  18. * will be useful, but WITHOUT ANY WARRANTY; without even the implied
  19. * ************************
  20. * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  21. * See the GNU General Public License for more details.
  22. *
  23. * You should have received a copy of the GNU General Public License
  24. * along with GNU CC; see the file COPYING. If not, see
  25. * <http://www.gnu.org/licenses/>.
  26. *
  27. * Please send any bug reports or fixes you make to the
  28. * email address(es):
  29. * lksctp developers <linux-sctp@vger.kernel.org>
  30. *
  31. * Written or modified by:
  32. * Xin Long <lucien.xin@gmail.com>
  33. */
  34. #include <linux/list.h>
  35. #include <net/sctp/sctp.h>
  36. #include <net/sctp/sm.h>
  37. #include <net/sctp/stream_sched.h>
  38. static struct flex_array *fa_alloc(size_t elem_size, size_t elem_count,
  39. gfp_t gfp)
  40. {
  41. struct flex_array *result;
  42. int err;
  43. result = flex_array_alloc(elem_size, elem_count, gfp);
  44. if (result) {
  45. err = flex_array_prealloc(result, 0, elem_count, gfp);
  46. if (err) {
  47. flex_array_free(result);
  48. result = NULL;
  49. }
  50. }
  51. return result;
  52. }
  53. static void fa_free(struct flex_array *fa)
  54. {
  55. if (fa)
  56. flex_array_free(fa);
  57. }
  58. static void fa_copy(struct flex_array *fa, struct flex_array *from,
  59. size_t index, size_t count)
  60. {
  61. void *elem;
  62. while (count--) {
  63. elem = flex_array_get(from, index);
  64. flex_array_put(fa, index, elem, 0);
  65. index++;
  66. }
  67. }
  68. static void fa_zero(struct flex_array *fa, size_t index, size_t count)
  69. {
  70. void *elem;
  71. while (count--) {
  72. elem = flex_array_get(fa, index);
  73. memset(elem, 0, fa->element_size);
  74. index++;
  75. }
  76. }
  77. static size_t fa_index(struct flex_array *fa, void *elem, size_t count)
  78. {
  79. size_t index = 0;
  80. while (count--) {
  81. if (elem == flex_array_get(fa, index))
  82. break;
  83. index++;
  84. }
  85. return index;
  86. }
  87. static void sctp_stream_shrink_out(struct sctp_stream *stream, __u16 outcnt)
  88. {
  89. struct sctp_association *asoc;
  90. struct sctp_chunk *ch, *temp;
  91. struct sctp_outq *outq;
  92. asoc = container_of(stream, struct sctp_association, stream);
  93. outq = &asoc->outqueue;
  94. list_for_each_entry_safe(ch, temp, &outq->out_chunk_list, list) {
  95. __u16 sid = sctp_chunk_stream_no(ch);
  96. if (sid < outcnt)
  97. continue;
  98. sctp_sched_dequeue_common(outq, ch);
  99. /* No need to call dequeue_done here because
  100. * the chunks are not scheduled by now.
  101. */
  102. /* Mark as failed send. */
  103. sctp_chunk_fail(ch, (__force __u32)SCTP_ERROR_INV_STRM);
  104. if (asoc->peer.prsctp_capable &&
  105. SCTP_PR_PRIO_ENABLED(ch->sinfo.sinfo_flags))
  106. asoc->sent_cnt_removable--;
  107. sctp_chunk_free(ch);
  108. }
  109. }
  110. /* Migrates chunks from stream queues to new stream queues if needed,
  111. * but not across associations. Also, removes those chunks to streams
  112. * higher than the new max.
  113. */
  114. static void sctp_stream_outq_migrate(struct sctp_stream *stream,
  115. struct sctp_stream *new, __u16 outcnt)
  116. {
  117. int i;
  118. if (stream->outcnt > outcnt)
  119. sctp_stream_shrink_out(stream, outcnt);
  120. if (new) {
  121. /* Here we actually move the old ext stuff into the new
  122. * buffer, because we want to keep it. Then
  123. * sctp_stream_update will swap ->out pointers.
  124. */
  125. for (i = 0; i < outcnt; i++) {
  126. kfree(SCTP_SO(new, i)->ext);
  127. SCTP_SO(new, i)->ext = SCTP_SO(stream, i)->ext;
  128. SCTP_SO(stream, i)->ext = NULL;
  129. }
  130. }
  131. for (i = outcnt; i < stream->outcnt; i++) {
  132. kfree(SCTP_SO(stream, i)->ext);
  133. SCTP_SO(stream, i)->ext = NULL;
  134. }
  135. }
  136. static int sctp_stream_alloc_out(struct sctp_stream *stream, __u16 outcnt,
  137. gfp_t gfp)
  138. {
  139. struct flex_array *out;
  140. size_t elem_size = sizeof(struct sctp_stream_out);
  141. out = fa_alloc(elem_size, outcnt, gfp);
  142. if (!out)
  143. return -ENOMEM;
  144. if (stream->out) {
  145. fa_copy(out, stream->out, 0, min(outcnt, stream->outcnt));
  146. if (stream->out_curr) {
  147. size_t index = fa_index(stream->out, stream->out_curr,
  148. stream->outcnt);
  149. BUG_ON(index == stream->outcnt);
  150. stream->out_curr = flex_array_get(out, index);
  151. }
  152. fa_free(stream->out);
  153. }
  154. if (outcnt > stream->outcnt)
  155. fa_zero(out, stream->outcnt, (outcnt - stream->outcnt));
  156. stream->out = out;
  157. return 0;
  158. }
  159. static int sctp_stream_alloc_in(struct sctp_stream *stream, __u16 incnt,
  160. gfp_t gfp)
  161. {
  162. struct flex_array *in;
  163. size_t elem_size = sizeof(struct sctp_stream_in);
  164. in = fa_alloc(elem_size, incnt, gfp);
  165. if (!in)
  166. return -ENOMEM;
  167. if (stream->in) {
  168. fa_copy(in, stream->in, 0, min(incnt, stream->incnt));
  169. fa_free(stream->in);
  170. }
  171. if (incnt > stream->incnt)
  172. fa_zero(in, stream->incnt, (incnt - stream->incnt));
  173. stream->in = in;
  174. return 0;
  175. }
  176. int sctp_stream_init(struct sctp_stream *stream, __u16 outcnt, __u16 incnt,
  177. gfp_t gfp)
  178. {
  179. struct sctp_sched_ops *sched = sctp_sched_ops_from_stream(stream);
  180. int i, ret = 0;
  181. gfp |= __GFP_NOWARN;
  182. /* Initial stream->out size may be very big, so free it and alloc
  183. * a new one with new outcnt to save memory if needed.
  184. */
  185. if (outcnt == stream->outcnt)
  186. goto in;
  187. /* Filter out chunks queued on streams that won't exist anymore */
  188. sched->unsched_all(stream);
  189. sctp_stream_outq_migrate(stream, NULL, outcnt);
  190. sched->sched_all(stream);
  191. ret = sctp_stream_alloc_out(stream, outcnt, gfp);
  192. if (ret)
  193. goto out;
  194. stream->outcnt = outcnt;
  195. for (i = 0; i < stream->outcnt; i++)
  196. SCTP_SO(stream, i)->state = SCTP_STREAM_OPEN;
  197. in:
  198. sctp_stream_interleave_init(stream);
  199. if (!incnt)
  200. goto out;
  201. ret = sctp_stream_alloc_in(stream, incnt, gfp);
  202. if (ret) {
  203. sched->free(stream);
  204. fa_free(stream->out);
  205. stream->out = NULL;
  206. stream->outcnt = 0;
  207. goto out;
  208. }
  209. stream->incnt = incnt;
  210. out:
  211. return ret;
  212. }
  213. int sctp_stream_init_ext(struct sctp_stream *stream, __u16 sid)
  214. {
  215. struct sctp_stream_out_ext *soute;
  216. int ret;
  217. soute = kzalloc(sizeof(*soute), GFP_KERNEL);
  218. if (!soute)
  219. return -ENOMEM;
  220. SCTP_SO(stream, sid)->ext = soute;
  221. ret = sctp_sched_init_sid(stream, sid, GFP_KERNEL);
  222. if (ret) {
  223. kfree(SCTP_SO(stream, sid)->ext);
  224. SCTP_SO(stream, sid)->ext = NULL;
  225. }
  226. return ret;
  227. }
  228. void sctp_stream_free(struct sctp_stream *stream)
  229. {
  230. struct sctp_sched_ops *sched = sctp_sched_ops_from_stream(stream);
  231. int i;
  232. sched->free(stream);
  233. for (i = 0; i < stream->outcnt; i++)
  234. kfree(SCTP_SO(stream, i)->ext);
  235. fa_free(stream->out);
  236. fa_free(stream->in);
  237. }
  238. void sctp_stream_clear(struct sctp_stream *stream)
  239. {
  240. int i;
  241. for (i = 0; i < stream->outcnt; i++) {
  242. SCTP_SO(stream, i)->mid = 0;
  243. SCTP_SO(stream, i)->mid_uo = 0;
  244. }
  245. for (i = 0; i < stream->incnt; i++)
  246. SCTP_SI(stream, i)->mid = 0;
  247. }
  248. void sctp_stream_update(struct sctp_stream *stream, struct sctp_stream *new)
  249. {
  250. struct sctp_sched_ops *sched = sctp_sched_ops_from_stream(stream);
  251. sched->unsched_all(stream);
  252. sctp_stream_outq_migrate(stream, new, new->outcnt);
  253. sctp_stream_free(stream);
  254. stream->out = new->out;
  255. stream->in = new->in;
  256. stream->outcnt = new->outcnt;
  257. stream->incnt = new->incnt;
  258. sched->sched_all(stream);
  259. new->out = NULL;
  260. new->in = NULL;
  261. new->outcnt = 0;
  262. new->incnt = 0;
  263. }
  264. static int sctp_send_reconf(struct sctp_association *asoc,
  265. struct sctp_chunk *chunk)
  266. {
  267. struct net *net = sock_net(asoc->base.sk);
  268. int retval = 0;
  269. retval = sctp_primitive_RECONF(net, asoc, chunk);
  270. if (retval)
  271. sctp_chunk_free(chunk);
  272. return retval;
  273. }
  274. static bool sctp_stream_outq_is_empty(struct sctp_stream *stream,
  275. __u16 str_nums, __be16 *str_list)
  276. {
  277. struct sctp_association *asoc;
  278. __u16 i;
  279. asoc = container_of(stream, struct sctp_association, stream);
  280. if (!asoc->outqueue.out_qlen)
  281. return true;
  282. if (!str_nums)
  283. return false;
  284. for (i = 0; i < str_nums; i++) {
  285. __u16 sid = ntohs(str_list[i]);
  286. if (SCTP_SO(stream, sid)->ext &&
  287. !list_empty(&SCTP_SO(stream, sid)->ext->outq))
  288. return false;
  289. }
  290. return true;
  291. }
  292. int sctp_send_reset_streams(struct sctp_association *asoc,
  293. struct sctp_reset_streams *params)
  294. {
  295. struct sctp_stream *stream = &asoc->stream;
  296. __u16 i, str_nums, *str_list;
  297. struct sctp_chunk *chunk;
  298. int retval = -EINVAL;
  299. __be16 *nstr_list;
  300. bool out, in;
  301. if (!asoc->peer.reconf_capable ||
  302. !(asoc->strreset_enable & SCTP_ENABLE_RESET_STREAM_REQ)) {
  303. retval = -ENOPROTOOPT;
  304. goto out;
  305. }
  306. if (asoc->strreset_outstanding) {
  307. retval = -EINPROGRESS;
  308. goto out;
  309. }
  310. out = params->srs_flags & SCTP_STREAM_RESET_OUTGOING;
  311. in = params->srs_flags & SCTP_STREAM_RESET_INCOMING;
  312. if (!out && !in)
  313. goto out;
  314. str_nums = params->srs_number_streams;
  315. str_list = params->srs_stream_list;
  316. if (str_nums) {
  317. int param_len = 0;
  318. if (out) {
  319. for (i = 0; i < str_nums; i++)
  320. if (str_list[i] >= stream->outcnt)
  321. goto out;
  322. param_len = str_nums * sizeof(__u16) +
  323. sizeof(struct sctp_strreset_outreq);
  324. }
  325. if (in) {
  326. for (i = 0; i < str_nums; i++)
  327. if (str_list[i] >= stream->incnt)
  328. goto out;
  329. param_len += str_nums * sizeof(__u16) +
  330. sizeof(struct sctp_strreset_inreq);
  331. }
  332. if (param_len > SCTP_MAX_CHUNK_LEN -
  333. sizeof(struct sctp_reconf_chunk))
  334. goto out;
  335. }
  336. nstr_list = kcalloc(str_nums, sizeof(__be16), GFP_KERNEL);
  337. if (!nstr_list) {
  338. retval = -ENOMEM;
  339. goto out;
  340. }
  341. for (i = 0; i < str_nums; i++)
  342. nstr_list[i] = htons(str_list[i]);
  343. if (out && !sctp_stream_outq_is_empty(stream, str_nums, nstr_list)) {
  344. kfree(nstr_list);
  345. retval = -EAGAIN;
  346. goto out;
  347. }
  348. chunk = sctp_make_strreset_req(asoc, str_nums, nstr_list, out, in);
  349. kfree(nstr_list);
  350. if (!chunk) {
  351. retval = -ENOMEM;
  352. goto out;
  353. }
  354. if (out) {
  355. if (str_nums)
  356. for (i = 0; i < str_nums; i++)
  357. SCTP_SO(stream, str_list[i])->state =
  358. SCTP_STREAM_CLOSED;
  359. else
  360. for (i = 0; i < stream->outcnt; i++)
  361. SCTP_SO(stream, i)->state = SCTP_STREAM_CLOSED;
  362. }
  363. asoc->strreset_chunk = chunk;
  364. sctp_chunk_hold(asoc->strreset_chunk);
  365. retval = sctp_send_reconf(asoc, chunk);
  366. if (retval) {
  367. sctp_chunk_put(asoc->strreset_chunk);
  368. asoc->strreset_chunk = NULL;
  369. if (!out)
  370. goto out;
  371. if (str_nums)
  372. for (i = 0; i < str_nums; i++)
  373. SCTP_SO(stream, str_list[i])->state =
  374. SCTP_STREAM_OPEN;
  375. else
  376. for (i = 0; i < stream->outcnt; i++)
  377. SCTP_SO(stream, i)->state = SCTP_STREAM_OPEN;
  378. goto out;
  379. }
  380. asoc->strreset_outstanding = out + in;
  381. out:
  382. return retval;
  383. }
  384. int sctp_send_reset_assoc(struct sctp_association *asoc)
  385. {
  386. struct sctp_stream *stream = &asoc->stream;
  387. struct sctp_chunk *chunk = NULL;
  388. int retval;
  389. __u16 i;
  390. if (!asoc->peer.reconf_capable ||
  391. !(asoc->strreset_enable & SCTP_ENABLE_RESET_ASSOC_REQ))
  392. return -ENOPROTOOPT;
  393. if (asoc->strreset_outstanding)
  394. return -EINPROGRESS;
  395. if (!sctp_outq_is_empty(&asoc->outqueue))
  396. return -EAGAIN;
  397. chunk = sctp_make_strreset_tsnreq(asoc);
  398. if (!chunk)
  399. return -ENOMEM;
  400. /* Block further xmit of data until this request is completed */
  401. for (i = 0; i < stream->outcnt; i++)
  402. SCTP_SO(stream, i)->state = SCTP_STREAM_CLOSED;
  403. asoc->strreset_chunk = chunk;
  404. sctp_chunk_hold(asoc->strreset_chunk);
  405. retval = sctp_send_reconf(asoc, chunk);
  406. if (retval) {
  407. sctp_chunk_put(asoc->strreset_chunk);
  408. asoc->strreset_chunk = NULL;
  409. for (i = 0; i < stream->outcnt; i++)
  410. SCTP_SO(stream, i)->state = SCTP_STREAM_OPEN;
  411. return retval;
  412. }
  413. asoc->strreset_outstanding = 1;
  414. return 0;
  415. }
  416. int sctp_send_add_streams(struct sctp_association *asoc,
  417. struct sctp_add_streams *params)
  418. {
  419. struct sctp_stream *stream = &asoc->stream;
  420. struct sctp_chunk *chunk = NULL;
  421. int retval;
  422. __u32 outcnt, incnt;
  423. __u16 out, in;
  424. if (!asoc->peer.reconf_capable ||
  425. !(asoc->strreset_enable & SCTP_ENABLE_CHANGE_ASSOC_REQ)) {
  426. retval = -ENOPROTOOPT;
  427. goto out;
  428. }
  429. if (asoc->strreset_outstanding) {
  430. retval = -EINPROGRESS;
  431. goto out;
  432. }
  433. out = params->sas_outstrms;
  434. in = params->sas_instrms;
  435. outcnt = stream->outcnt + out;
  436. incnt = stream->incnt + in;
  437. if (outcnt > SCTP_MAX_STREAM || incnt > SCTP_MAX_STREAM ||
  438. (!out && !in)) {
  439. retval = -EINVAL;
  440. goto out;
  441. }
  442. if (out) {
  443. retval = sctp_stream_alloc_out(stream, outcnt, GFP_KERNEL);
  444. if (retval)
  445. goto out;
  446. }
  447. chunk = sctp_make_strreset_addstrm(asoc, out, in);
  448. if (!chunk) {
  449. retval = -ENOMEM;
  450. goto out;
  451. }
  452. asoc->strreset_chunk = chunk;
  453. sctp_chunk_hold(asoc->strreset_chunk);
  454. retval = sctp_send_reconf(asoc, chunk);
  455. if (retval) {
  456. sctp_chunk_put(asoc->strreset_chunk);
  457. asoc->strreset_chunk = NULL;
  458. goto out;
  459. }
  460. stream->outcnt = outcnt;
  461. asoc->strreset_outstanding = !!out + !!in;
  462. out:
  463. return retval;
  464. }
  465. static struct sctp_paramhdr *sctp_chunk_lookup_strreset_param(
  466. struct sctp_association *asoc, __be32 resp_seq,
  467. __be16 type)
  468. {
  469. struct sctp_chunk *chunk = asoc->strreset_chunk;
  470. struct sctp_reconf_chunk *hdr;
  471. union sctp_params param;
  472. if (!chunk)
  473. return NULL;
  474. hdr = (struct sctp_reconf_chunk *)chunk->chunk_hdr;
  475. sctp_walk_params(param, hdr, params) {
  476. /* sctp_strreset_tsnreq is actually the basic structure
  477. * of all stream reconf params, so it's safe to use it
  478. * to access request_seq.
  479. */
  480. struct sctp_strreset_tsnreq *req = param.v;
  481. if ((!resp_seq || req->request_seq == resp_seq) &&
  482. (!type || type == req->param_hdr.type))
  483. return param.v;
  484. }
  485. return NULL;
  486. }
  487. static void sctp_update_strreset_result(struct sctp_association *asoc,
  488. __u32 result)
  489. {
  490. asoc->strreset_result[1] = asoc->strreset_result[0];
  491. asoc->strreset_result[0] = result;
  492. }
  493. struct sctp_chunk *sctp_process_strreset_outreq(
  494. struct sctp_association *asoc,
  495. union sctp_params param,
  496. struct sctp_ulpevent **evp)
  497. {
  498. struct sctp_strreset_outreq *outreq = param.v;
  499. struct sctp_stream *stream = &asoc->stream;
  500. __u32 result = SCTP_STRRESET_DENIED;
  501. __be16 *str_p = NULL;
  502. __u32 request_seq;
  503. __u16 i, nums;
  504. request_seq = ntohl(outreq->request_seq);
  505. if (ntohl(outreq->send_reset_at_tsn) >
  506. sctp_tsnmap_get_ctsn(&asoc->peer.tsn_map)) {
  507. result = SCTP_STRRESET_IN_PROGRESS;
  508. goto err;
  509. }
  510. if (TSN_lt(asoc->strreset_inseq, request_seq) ||
  511. TSN_lt(request_seq, asoc->strreset_inseq - 2)) {
  512. result = SCTP_STRRESET_ERR_BAD_SEQNO;
  513. goto err;
  514. } else if (TSN_lt(request_seq, asoc->strreset_inseq)) {
  515. i = asoc->strreset_inseq - request_seq - 1;
  516. result = asoc->strreset_result[i];
  517. goto err;
  518. }
  519. asoc->strreset_inseq++;
  520. /* Check strreset_enable after inseq inc, as sender cannot tell
  521. * the peer doesn't enable strreset after receiving response with
  522. * result denied, as well as to keep consistent with bsd.
  523. */
  524. if (!(asoc->strreset_enable & SCTP_ENABLE_RESET_STREAM_REQ))
  525. goto out;
  526. nums = (ntohs(param.p->length) - sizeof(*outreq)) / sizeof(__u16);
  527. str_p = outreq->list_of_streams;
  528. for (i = 0; i < nums; i++) {
  529. if (ntohs(str_p[i]) >= stream->incnt) {
  530. result = SCTP_STRRESET_ERR_WRONG_SSN;
  531. goto out;
  532. }
  533. }
  534. if (asoc->strreset_chunk) {
  535. if (!sctp_chunk_lookup_strreset_param(
  536. asoc, outreq->response_seq,
  537. SCTP_PARAM_RESET_IN_REQUEST)) {
  538. /* same process with outstanding isn't 0 */
  539. result = SCTP_STRRESET_ERR_IN_PROGRESS;
  540. goto out;
  541. }
  542. asoc->strreset_outstanding--;
  543. asoc->strreset_outseq++;
  544. if (!asoc->strreset_outstanding) {
  545. struct sctp_transport *t;
  546. t = asoc->strreset_chunk->transport;
  547. if (del_timer(&t->reconf_timer))
  548. sctp_transport_put(t);
  549. sctp_chunk_put(asoc->strreset_chunk);
  550. asoc->strreset_chunk = NULL;
  551. }
  552. }
  553. if (nums)
  554. for (i = 0; i < nums; i++)
  555. SCTP_SI(stream, ntohs(str_p[i]))->mid = 0;
  556. else
  557. for (i = 0; i < stream->incnt; i++)
  558. SCTP_SI(stream, i)->mid = 0;
  559. result = SCTP_STRRESET_PERFORMED;
  560. *evp = sctp_ulpevent_make_stream_reset_event(asoc,
  561. SCTP_STREAM_RESET_INCOMING_SSN, nums, str_p, GFP_ATOMIC);
  562. out:
  563. sctp_update_strreset_result(asoc, result);
  564. err:
  565. return sctp_make_strreset_resp(asoc, result, request_seq);
  566. }
  567. struct sctp_chunk *sctp_process_strreset_inreq(
  568. struct sctp_association *asoc,
  569. union sctp_params param,
  570. struct sctp_ulpevent **evp)
  571. {
  572. struct sctp_strreset_inreq *inreq = param.v;
  573. struct sctp_stream *stream = &asoc->stream;
  574. __u32 result = SCTP_STRRESET_DENIED;
  575. struct sctp_chunk *chunk = NULL;
  576. __u32 request_seq;
  577. __u16 i, nums;
  578. __be16 *str_p;
  579. request_seq = ntohl(inreq->request_seq);
  580. if (TSN_lt(asoc->strreset_inseq, request_seq) ||
  581. TSN_lt(request_seq, asoc->strreset_inseq - 2)) {
  582. result = SCTP_STRRESET_ERR_BAD_SEQNO;
  583. goto err;
  584. } else if (TSN_lt(request_seq, asoc->strreset_inseq)) {
  585. i = asoc->strreset_inseq - request_seq - 1;
  586. result = asoc->strreset_result[i];
  587. if (result == SCTP_STRRESET_PERFORMED)
  588. return NULL;
  589. goto err;
  590. }
  591. asoc->strreset_inseq++;
  592. if (!(asoc->strreset_enable & SCTP_ENABLE_RESET_STREAM_REQ))
  593. goto out;
  594. if (asoc->strreset_outstanding) {
  595. result = SCTP_STRRESET_ERR_IN_PROGRESS;
  596. goto out;
  597. }
  598. nums = (ntohs(param.p->length) - sizeof(*inreq)) / sizeof(__u16);
  599. str_p = inreq->list_of_streams;
  600. for (i = 0; i < nums; i++) {
  601. if (ntohs(str_p[i]) >= stream->outcnt) {
  602. result = SCTP_STRRESET_ERR_WRONG_SSN;
  603. goto out;
  604. }
  605. }
  606. if (!sctp_stream_outq_is_empty(stream, nums, str_p)) {
  607. result = SCTP_STRRESET_IN_PROGRESS;
  608. asoc->strreset_inseq--;
  609. goto err;
  610. }
  611. chunk = sctp_make_strreset_req(asoc, nums, str_p, 1, 0);
  612. if (!chunk)
  613. goto out;
  614. if (nums)
  615. for (i = 0; i < nums; i++)
  616. SCTP_SO(stream, ntohs(str_p[i]))->state =
  617. SCTP_STREAM_CLOSED;
  618. else
  619. for (i = 0; i < stream->outcnt; i++)
  620. SCTP_SO(stream, i)->state = SCTP_STREAM_CLOSED;
  621. asoc->strreset_chunk = chunk;
  622. asoc->strreset_outstanding = 1;
  623. sctp_chunk_hold(asoc->strreset_chunk);
  624. result = SCTP_STRRESET_PERFORMED;
  625. out:
  626. sctp_update_strreset_result(asoc, result);
  627. err:
  628. if (!chunk)
  629. chunk = sctp_make_strreset_resp(asoc, result, request_seq);
  630. return chunk;
  631. }
  632. struct sctp_chunk *sctp_process_strreset_tsnreq(
  633. struct sctp_association *asoc,
  634. union sctp_params param,
  635. struct sctp_ulpevent **evp)
  636. {
  637. __u32 init_tsn = 0, next_tsn = 0, max_tsn_seen;
  638. struct sctp_strreset_tsnreq *tsnreq = param.v;
  639. struct sctp_stream *stream = &asoc->stream;
  640. __u32 result = SCTP_STRRESET_DENIED;
  641. __u32 request_seq;
  642. __u16 i;
  643. request_seq = ntohl(tsnreq->request_seq);
  644. if (TSN_lt(asoc->strreset_inseq, request_seq) ||
  645. TSN_lt(request_seq, asoc->strreset_inseq - 2)) {
  646. result = SCTP_STRRESET_ERR_BAD_SEQNO;
  647. goto err;
  648. } else if (TSN_lt(request_seq, asoc->strreset_inseq)) {
  649. i = asoc->strreset_inseq - request_seq - 1;
  650. result = asoc->strreset_result[i];
  651. if (result == SCTP_STRRESET_PERFORMED) {
  652. next_tsn = asoc->ctsn_ack_point + 1;
  653. init_tsn =
  654. sctp_tsnmap_get_ctsn(&asoc->peer.tsn_map) + 1;
  655. }
  656. goto err;
  657. }
  658. if (!sctp_outq_is_empty(&asoc->outqueue)) {
  659. result = SCTP_STRRESET_IN_PROGRESS;
  660. goto err;
  661. }
  662. asoc->strreset_inseq++;
  663. if (!(asoc->strreset_enable & SCTP_ENABLE_RESET_ASSOC_REQ))
  664. goto out;
  665. if (asoc->strreset_outstanding) {
  666. result = SCTP_STRRESET_ERR_IN_PROGRESS;
  667. goto out;
  668. }
  669. /* G4: The same processing as though a FWD-TSN chunk (as defined in
  670. * [RFC3758]) with all streams affected and a new cumulative TSN
  671. * ACK of the Receiver's Next TSN minus 1 were received MUST be
  672. * performed.
  673. */
  674. max_tsn_seen = sctp_tsnmap_get_max_tsn_seen(&asoc->peer.tsn_map);
  675. asoc->stream.si->report_ftsn(&asoc->ulpq, max_tsn_seen);
  676. /* G1: Compute an appropriate value for the Receiver's Next TSN -- the
  677. * TSN that the peer should use to send the next DATA chunk. The
  678. * value SHOULD be the smallest TSN not acknowledged by the
  679. * receiver of the request plus 2^31.
  680. */
  681. init_tsn = sctp_tsnmap_get_ctsn(&asoc->peer.tsn_map) + (1 << 31);
  682. sctp_tsnmap_init(&asoc->peer.tsn_map, SCTP_TSN_MAP_INITIAL,
  683. init_tsn, GFP_ATOMIC);
  684. /* G3: The same processing as though a SACK chunk with no gap report
  685. * and a cumulative TSN ACK of the Sender's Next TSN minus 1 were
  686. * received MUST be performed.
  687. */
  688. sctp_outq_free(&asoc->outqueue);
  689. /* G2: Compute an appropriate value for the local endpoint's next TSN,
  690. * i.e., the next TSN assigned by the receiver of the SSN/TSN reset
  691. * chunk. The value SHOULD be the highest TSN sent by the receiver
  692. * of the request plus 1.
  693. */
  694. next_tsn = asoc->next_tsn;
  695. asoc->ctsn_ack_point = next_tsn - 1;
  696. asoc->adv_peer_ack_point = asoc->ctsn_ack_point;
  697. /* G5: The next expected and outgoing SSNs MUST be reset to 0 for all
  698. * incoming and outgoing streams.
  699. */
  700. for (i = 0; i < stream->outcnt; i++) {
  701. SCTP_SO(stream, i)->mid = 0;
  702. SCTP_SO(stream, i)->mid_uo = 0;
  703. }
  704. for (i = 0; i < stream->incnt; i++)
  705. SCTP_SI(stream, i)->mid = 0;
  706. result = SCTP_STRRESET_PERFORMED;
  707. *evp = sctp_ulpevent_make_assoc_reset_event(asoc, 0, init_tsn,
  708. next_tsn, GFP_ATOMIC);
  709. out:
  710. sctp_update_strreset_result(asoc, result);
  711. err:
  712. return sctp_make_strreset_tsnresp(asoc, result, request_seq,
  713. next_tsn, init_tsn);
  714. }
  715. struct sctp_chunk *sctp_process_strreset_addstrm_out(
  716. struct sctp_association *asoc,
  717. union sctp_params param,
  718. struct sctp_ulpevent **evp)
  719. {
  720. struct sctp_strreset_addstrm *addstrm = param.v;
  721. struct sctp_stream *stream = &asoc->stream;
  722. __u32 result = SCTP_STRRESET_DENIED;
  723. __u32 request_seq, incnt;
  724. __u16 in, i;
  725. request_seq = ntohl(addstrm->request_seq);
  726. if (TSN_lt(asoc->strreset_inseq, request_seq) ||
  727. TSN_lt(request_seq, asoc->strreset_inseq - 2)) {
  728. result = SCTP_STRRESET_ERR_BAD_SEQNO;
  729. goto err;
  730. } else if (TSN_lt(request_seq, asoc->strreset_inseq)) {
  731. i = asoc->strreset_inseq - request_seq - 1;
  732. result = asoc->strreset_result[i];
  733. goto err;
  734. }
  735. asoc->strreset_inseq++;
  736. if (!(asoc->strreset_enable & SCTP_ENABLE_CHANGE_ASSOC_REQ))
  737. goto out;
  738. in = ntohs(addstrm->number_of_streams);
  739. incnt = stream->incnt + in;
  740. if (!in || incnt > SCTP_MAX_STREAM)
  741. goto out;
  742. if (sctp_stream_alloc_in(stream, incnt, GFP_ATOMIC))
  743. goto out;
  744. if (asoc->strreset_chunk) {
  745. if (!sctp_chunk_lookup_strreset_param(
  746. asoc, 0, SCTP_PARAM_RESET_ADD_IN_STREAMS)) {
  747. /* same process with outstanding isn't 0 */
  748. result = SCTP_STRRESET_ERR_IN_PROGRESS;
  749. goto out;
  750. }
  751. asoc->strreset_outstanding--;
  752. asoc->strreset_outseq++;
  753. if (!asoc->strreset_outstanding) {
  754. struct sctp_transport *t;
  755. t = asoc->strreset_chunk->transport;
  756. if (del_timer(&t->reconf_timer))
  757. sctp_transport_put(t);
  758. sctp_chunk_put(asoc->strreset_chunk);
  759. asoc->strreset_chunk = NULL;
  760. }
  761. }
  762. stream->incnt = incnt;
  763. result = SCTP_STRRESET_PERFORMED;
  764. *evp = sctp_ulpevent_make_stream_change_event(asoc,
  765. 0, ntohs(addstrm->number_of_streams), 0, GFP_ATOMIC);
  766. out:
  767. sctp_update_strreset_result(asoc, result);
  768. err:
  769. return sctp_make_strreset_resp(asoc, result, request_seq);
  770. }
  771. struct sctp_chunk *sctp_process_strreset_addstrm_in(
  772. struct sctp_association *asoc,
  773. union sctp_params param,
  774. struct sctp_ulpevent **evp)
  775. {
  776. struct sctp_strreset_addstrm *addstrm = param.v;
  777. struct sctp_stream *stream = &asoc->stream;
  778. __u32 result = SCTP_STRRESET_DENIED;
  779. struct sctp_chunk *chunk = NULL;
  780. __u32 request_seq, outcnt;
  781. __u16 out, i;
  782. int ret;
  783. request_seq = ntohl(addstrm->request_seq);
  784. if (TSN_lt(asoc->strreset_inseq, request_seq) ||
  785. TSN_lt(request_seq, asoc->strreset_inseq - 2)) {
  786. result = SCTP_STRRESET_ERR_BAD_SEQNO;
  787. goto err;
  788. } else if (TSN_lt(request_seq, asoc->strreset_inseq)) {
  789. i = asoc->strreset_inseq - request_seq - 1;
  790. result = asoc->strreset_result[i];
  791. if (result == SCTP_STRRESET_PERFORMED)
  792. return NULL;
  793. goto err;
  794. }
  795. asoc->strreset_inseq++;
  796. if (!(asoc->strreset_enable & SCTP_ENABLE_CHANGE_ASSOC_REQ))
  797. goto out;
  798. if (asoc->strreset_outstanding) {
  799. result = SCTP_STRRESET_ERR_IN_PROGRESS;
  800. goto out;
  801. }
  802. out = ntohs(addstrm->number_of_streams);
  803. outcnt = stream->outcnt + out;
  804. if (!out || outcnt > SCTP_MAX_STREAM)
  805. goto out;
  806. ret = sctp_stream_alloc_out(stream, outcnt, GFP_ATOMIC);
  807. if (ret)
  808. goto out;
  809. chunk = sctp_make_strreset_addstrm(asoc, out, 0);
  810. if (!chunk)
  811. goto out;
  812. asoc->strreset_chunk = chunk;
  813. asoc->strreset_outstanding = 1;
  814. sctp_chunk_hold(asoc->strreset_chunk);
  815. stream->outcnt = outcnt;
  816. result = SCTP_STRRESET_PERFORMED;
  817. out:
  818. sctp_update_strreset_result(asoc, result);
  819. err:
  820. if (!chunk)
  821. chunk = sctp_make_strreset_resp(asoc, result, request_seq);
  822. return chunk;
  823. }
  824. struct sctp_chunk *sctp_process_strreset_resp(
  825. struct sctp_association *asoc,
  826. union sctp_params param,
  827. struct sctp_ulpevent **evp)
  828. {
  829. struct sctp_stream *stream = &asoc->stream;
  830. struct sctp_strreset_resp *resp = param.v;
  831. struct sctp_transport *t;
  832. __u16 i, nums, flags = 0;
  833. struct sctp_paramhdr *req;
  834. __u32 result;
  835. req = sctp_chunk_lookup_strreset_param(asoc, resp->response_seq, 0);
  836. if (!req)
  837. return NULL;
  838. result = ntohl(resp->result);
  839. if (result != SCTP_STRRESET_PERFORMED) {
  840. /* if in progress, do nothing but retransmit */
  841. if (result == SCTP_STRRESET_IN_PROGRESS)
  842. return NULL;
  843. else if (result == SCTP_STRRESET_DENIED)
  844. flags = SCTP_STREAM_RESET_DENIED;
  845. else
  846. flags = SCTP_STREAM_RESET_FAILED;
  847. }
  848. if (req->type == SCTP_PARAM_RESET_OUT_REQUEST) {
  849. struct sctp_strreset_outreq *outreq;
  850. __be16 *str_p;
  851. outreq = (struct sctp_strreset_outreq *)req;
  852. str_p = outreq->list_of_streams;
  853. nums = (ntohs(outreq->param_hdr.length) - sizeof(*outreq)) /
  854. sizeof(__u16);
  855. if (result == SCTP_STRRESET_PERFORMED) {
  856. struct sctp_stream_out *sout;
  857. if (nums) {
  858. for (i = 0; i < nums; i++) {
  859. sout = SCTP_SO(stream, ntohs(str_p[i]));
  860. sout->mid = 0;
  861. sout->mid_uo = 0;
  862. }
  863. } else {
  864. for (i = 0; i < stream->outcnt; i++) {
  865. sout = SCTP_SO(stream, i);
  866. sout->mid = 0;
  867. sout->mid_uo = 0;
  868. }
  869. }
  870. }
  871. flags |= SCTP_STREAM_RESET_OUTGOING_SSN;
  872. for (i = 0; i < stream->outcnt; i++)
  873. SCTP_SO(stream, i)->state = SCTP_STREAM_OPEN;
  874. *evp = sctp_ulpevent_make_stream_reset_event(asoc, flags,
  875. nums, str_p, GFP_ATOMIC);
  876. } else if (req->type == SCTP_PARAM_RESET_IN_REQUEST) {
  877. struct sctp_strreset_inreq *inreq;
  878. __be16 *str_p;
  879. /* if the result is performed, it's impossible for inreq */
  880. if (result == SCTP_STRRESET_PERFORMED)
  881. return NULL;
  882. inreq = (struct sctp_strreset_inreq *)req;
  883. str_p = inreq->list_of_streams;
  884. nums = (ntohs(inreq->param_hdr.length) - sizeof(*inreq)) /
  885. sizeof(__u16);
  886. flags |= SCTP_STREAM_RESET_INCOMING_SSN;
  887. *evp = sctp_ulpevent_make_stream_reset_event(asoc, flags,
  888. nums, str_p, GFP_ATOMIC);
  889. } else if (req->type == SCTP_PARAM_RESET_TSN_REQUEST) {
  890. struct sctp_strreset_resptsn *resptsn;
  891. __u32 stsn, rtsn;
  892. /* check for resptsn, as sctp_verify_reconf didn't do it*/
  893. if (ntohs(param.p->length) != sizeof(*resptsn))
  894. return NULL;
  895. resptsn = (struct sctp_strreset_resptsn *)resp;
  896. stsn = ntohl(resptsn->senders_next_tsn);
  897. rtsn = ntohl(resptsn->receivers_next_tsn);
  898. if (result == SCTP_STRRESET_PERFORMED) {
  899. __u32 mtsn = sctp_tsnmap_get_max_tsn_seen(
  900. &asoc->peer.tsn_map);
  901. LIST_HEAD(temp);
  902. asoc->stream.si->report_ftsn(&asoc->ulpq, mtsn);
  903. sctp_tsnmap_init(&asoc->peer.tsn_map,
  904. SCTP_TSN_MAP_INITIAL,
  905. stsn, GFP_ATOMIC);
  906. /* Clean up sacked and abandoned queues only. As the
  907. * out_chunk_list may not be empty, splice it to temp,
  908. * then get it back after sctp_outq_free is done.
  909. */
  910. list_splice_init(&asoc->outqueue.out_chunk_list, &temp);
  911. sctp_outq_free(&asoc->outqueue);
  912. list_splice_init(&temp, &asoc->outqueue.out_chunk_list);
  913. asoc->next_tsn = rtsn;
  914. asoc->ctsn_ack_point = asoc->next_tsn - 1;
  915. asoc->adv_peer_ack_point = asoc->ctsn_ack_point;
  916. for (i = 0; i < stream->outcnt; i++) {
  917. SCTP_SO(stream, i)->mid = 0;
  918. SCTP_SO(stream, i)->mid_uo = 0;
  919. }
  920. for (i = 0; i < stream->incnt; i++)
  921. SCTP_SI(stream, i)->mid = 0;
  922. }
  923. for (i = 0; i < stream->outcnt; i++)
  924. SCTP_SO(stream, i)->state = SCTP_STREAM_OPEN;
  925. *evp = sctp_ulpevent_make_assoc_reset_event(asoc, flags,
  926. stsn, rtsn, GFP_ATOMIC);
  927. } else if (req->type == SCTP_PARAM_RESET_ADD_OUT_STREAMS) {
  928. struct sctp_strreset_addstrm *addstrm;
  929. __u16 number;
  930. addstrm = (struct sctp_strreset_addstrm *)req;
  931. nums = ntohs(addstrm->number_of_streams);
  932. number = stream->outcnt - nums;
  933. if (result == SCTP_STRRESET_PERFORMED) {
  934. for (i = number; i < stream->outcnt; i++)
  935. SCTP_SO(stream, i)->state = SCTP_STREAM_OPEN;
  936. } else {
  937. sctp_stream_shrink_out(stream, number);
  938. stream->outcnt = number;
  939. }
  940. *evp = sctp_ulpevent_make_stream_change_event(asoc, flags,
  941. 0, nums, GFP_ATOMIC);
  942. } else if (req->type == SCTP_PARAM_RESET_ADD_IN_STREAMS) {
  943. struct sctp_strreset_addstrm *addstrm;
  944. /* if the result is performed, it's impossible for addstrm in
  945. * request.
  946. */
  947. if (result == SCTP_STRRESET_PERFORMED)
  948. return NULL;
  949. addstrm = (struct sctp_strreset_addstrm *)req;
  950. nums = ntohs(addstrm->number_of_streams);
  951. *evp = sctp_ulpevent_make_stream_change_event(asoc, flags,
  952. nums, 0, GFP_ATOMIC);
  953. }
  954. asoc->strreset_outstanding--;
  955. asoc->strreset_outseq++;
  956. /* remove everything for this reconf request */
  957. if (!asoc->strreset_outstanding) {
  958. t = asoc->strreset_chunk->transport;
  959. if (del_timer(&t->reconf_timer))
  960. sctp_transport_put(t);
  961. sctp_chunk_put(asoc->strreset_chunk);
  962. asoc->strreset_chunk = NULL;
  963. }
  964. return NULL;
  965. }