stream.c 28 KB

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