Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

sctp: implement handle_ftsn for sctp_stream_interleave

handle_ftsn is added as a member of sctp_stream_interleave, used to skip
ssn for data or mid for idata, called for SCTP_CMD_PROCESS_FWDTSN cmd.

sctp_handle_iftsn works for ifwdtsn, and sctp_handle_fwdtsn works for
fwdtsn. Note that different from sctp_handle_fwdtsn, sctp_handle_iftsn
could do stream abort pd.

Signed-off-by: Xin Long <lucien.xin@gmail.com>
Acked-by: Marcelo R. Leitner <marcelo.leitner@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Xin Long and committed by
David S. Miller
de60fe91 47b20a88

+53 -13
+2
include/net/sctp/stream_interleave.h
··· 52 52 void (*generate_ftsn)(struct sctp_outq *q, __u32 ctsn); 53 53 bool (*validate_ftsn)(struct sctp_chunk *chunk); 54 54 void (*report_ftsn)(struct sctp_ulpq *ulpq, __u32 ftsn); 55 + void (*handle_ftsn)(struct sctp_ulpq *ulpq, 56 + struct sctp_chunk *chunk); 55 57 }; 56 58 57 59 void sctp_stream_interleave_init(struct sctp_stream *stream);
+2 -13
net/sctp/sm_sideeffect.c
··· 1007 1007 } 1008 1008 } 1009 1009 1010 - /* Process variable FWDTSN chunk information. */ 1011 - static void sctp_cmd_process_fwdtsn(struct sctp_ulpq *ulpq, 1012 - struct sctp_chunk *chunk) 1013 - { 1014 - struct sctp_fwdtsn_skip *skip; 1015 - 1016 - /* Walk through all the skipped SSNs */ 1017 - sctp_walk_fwdtsn(skip, chunk) { 1018 - sctp_ulpq_skip(ulpq, ntohs(skip->stream), ntohs(skip->ssn)); 1019 - } 1020 - } 1021 - 1022 1010 /* Helper function to remove the association non-primary peer 1023 1011 * transports. 1024 1012 */ ··· 1360 1372 break; 1361 1373 1362 1374 case SCTP_CMD_PROCESS_FWDTSN: 1363 - sctp_cmd_process_fwdtsn(&asoc->ulpq, cmd->obj.chunk); 1375 + asoc->stream.si->handle_ftsn(&asoc->ulpq, 1376 + cmd->obj.chunk); 1364 1377 break; 1365 1378 1366 1379 case SCTP_CMD_GEN_SACK:
+49
net/sctp/stream_interleave.c
··· 1239 1239 sctp_intl_abort_pd(ulpq, GFP_ATOMIC); 1240 1240 } 1241 1241 1242 + static void sctp_handle_fwdtsn(struct sctp_ulpq *ulpq, struct sctp_chunk *chunk) 1243 + { 1244 + struct sctp_fwdtsn_skip *skip; 1245 + 1246 + /* Walk through all the skipped SSNs */ 1247 + sctp_walk_fwdtsn(skip, chunk) 1248 + sctp_ulpq_skip(ulpq, ntohs(skip->stream), ntohs(skip->ssn)); 1249 + } 1250 + 1251 + static void sctp_intl_skip(struct sctp_ulpq *ulpq, __u16 sid, __u32 mid, 1252 + __u8 flags) 1253 + { 1254 + struct sctp_stream_in *sin = sctp_stream_in(ulpq->asoc, sid); 1255 + struct sctp_stream *stream = &ulpq->asoc->stream; 1256 + 1257 + if (flags & SCTP_FTSN_U_BIT) { 1258 + if (sin->pd_mode_uo && MID_lt(sin->mid_uo, mid)) { 1259 + sin->pd_mode_uo = 0; 1260 + sctp_intl_stream_abort_pd(ulpq, sid, mid, 0x1, 1261 + GFP_ATOMIC); 1262 + } 1263 + return; 1264 + } 1265 + 1266 + if (MID_lt(mid, sctp_mid_peek(stream, in, sid))) 1267 + return; 1268 + 1269 + if (sin->pd_mode) { 1270 + sin->pd_mode = 0; 1271 + sctp_intl_stream_abort_pd(ulpq, sid, mid, 0x0, GFP_ATOMIC); 1272 + } 1273 + 1274 + sctp_mid_skip(stream, in, sid, mid); 1275 + 1276 + sctp_intl_reap_ordered(ulpq, sid); 1277 + } 1278 + 1279 + static void sctp_handle_iftsn(struct sctp_ulpq *ulpq, struct sctp_chunk *chunk) 1280 + { 1281 + struct sctp_ifwdtsn_skip *skip; 1282 + 1283 + /* Walk through all the skipped MIDs and abort stream pd if possible */ 1284 + sctp_walk_ifwdtsn(skip, chunk) 1285 + sctp_intl_skip(ulpq, ntohs(skip->stream), 1286 + ntohl(skip->mid), skip->flags); 1287 + } 1288 + 1242 1289 static struct sctp_stream_interleave sctp_stream_interleave_0 = { 1243 1290 .data_chunk_len = sizeof(struct sctp_data_chunk), 1244 1291 .ftsn_chunk_len = sizeof(struct sctp_fwdtsn_chunk), ··· 1302 1255 .generate_ftsn = sctp_generate_fwdtsn, 1303 1256 .validate_ftsn = sctp_validate_fwdtsn, 1304 1257 .report_ftsn = sctp_report_fwdtsn, 1258 + .handle_ftsn = sctp_handle_fwdtsn, 1305 1259 }; 1306 1260 1307 1261 static struct sctp_stream_interleave sctp_stream_interleave_1 = { ··· 1321 1273 .generate_ftsn = sctp_generate_iftsn, 1322 1274 .validate_ftsn = sctp_validate_iftsn, 1323 1275 .report_ftsn = sctp_report_iftsn, 1276 + .handle_ftsn = sctp_handle_iftsn, 1324 1277 }; 1325 1278 1326 1279 void sctp_stream_interleave_init(struct sctp_stream *stream)