summaryrefslogtreecommitdiffstats
path: root/net/sctp
diff options
context:
space:
mode:
authorMarcelo Ricardo Leitner <marcelo.leitner@gmail.com>2018-05-14 13:34:43 -0400
committerDavid S. Miller <davem@davemloft.net>2018-05-14 22:57:15 -0400
commit4fdbb0efb9de51295071fdf968d476c1f0605d21 (patch)
tree97b8c17a71566857c739a0519dbbb8cafbc902e9 /net/sctp
parent6605f694823965fe53ce761dad3aaf965861dc7e (diff)
sctp: rework switch cases in sctp_outq_flush_data
Remove an inner one, which tended to be error prone due to the cascading and it can be replaced by a simple if (). Rework the outer one so that the actual flush code is not inside it. Now we first validate if we can or cannot send data, return if not, and then the flush code. Suggested-by: Xin Long <lucien.xin@gmail.com> Signed-off-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sctp')
-rw-r--r--net/sctp/outqueue.c191
1 files changed, 93 insertions, 98 deletions
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c
index e1632b8e2900..e9c22b3db11c 100644
--- a/net/sctp/outqueue.c
+++ b/net/sctp/outqueue.c
@@ -1058,122 +1058,117 @@ static void sctp_outq_flush_data(struct sctp_outq *q,
1058 * chunk. 1058 * chunk.
1059 */ 1059 */
1060 if (!packet || !packet->has_cookie_echo) 1060 if (!packet || !packet->has_cookie_echo)
1061 break; 1061 return;
1062 1062
1063 /* fallthru */ 1063 /* fallthru */
1064 case SCTP_STATE_ESTABLISHED: 1064 case SCTP_STATE_ESTABLISHED:
1065 case SCTP_STATE_SHUTDOWN_PENDING: 1065 case SCTP_STATE_SHUTDOWN_PENDING:
1066 case SCTP_STATE_SHUTDOWN_RECEIVED: 1066 case SCTP_STATE_SHUTDOWN_RECEIVED:
1067 /* 1067 break;
1068 * RFC 2960 6.1 Transmission of DATA Chunks
1069 *
1070 * C) When the time comes for the sender to transmit,
1071 * before sending new DATA chunks, the sender MUST
1072 * first transmit any outstanding DATA chunks which
1073 * are marked for retransmission (limited by the
1074 * current cwnd).
1075 */
1076 if (!list_empty(&q->retransmit)) {
1077 if (!sctp_outq_flush_rtx(q, _transport, transport_list,
1078 rtx_timeout, gfp))
1079 break;
1080 /* We may have switched current transport */
1081 transport = *_transport;
1082 packet = &transport->packet;
1083 }
1084 1068
1085 /* Apply Max.Burst limitation to the current transport in 1069 default:
1086 * case it will be used for new data. We are going to 1070 /* Do nothing. */
1087 * rest it before we return, but we want to apply the limit 1071 return;
1088 * to the currently queued data. 1072 }
1089 */
1090 if (transport)
1091 sctp_transport_burst_limited(transport);
1092
1093 /* Finally, transmit new packets. */
1094 while ((chunk = sctp_outq_dequeue_data(q)) != NULL) {
1095 __u32 sid = ntohs(chunk->subh.data_hdr->stream);
1096
1097 /* Has this chunk expired? */
1098 if (sctp_chunk_abandoned(chunk)) {
1099 sctp_sched_dequeue_done(q, chunk);
1100 sctp_chunk_fail(chunk, 0);
1101 sctp_chunk_free(chunk);
1102 continue;
1103 }
1104 1073
1105 if (asoc->stream.out[sid].state == SCTP_STREAM_CLOSED) { 1074 /*
1106 sctp_outq_head_data(q, chunk); 1075 * RFC 2960 6.1 Transmission of DATA Chunks
1107 break; 1076 *
1108 } 1077 * C) When the time comes for the sender to transmit,
1078 * before sending new DATA chunks, the sender MUST
1079 * first transmit any outstanding DATA chunks which
1080 * are marked for retransmission (limited by the
1081 * current cwnd).
1082 */
1083 if (!list_empty(&q->retransmit)) {
1084 if (!sctp_outq_flush_rtx(q, _transport, transport_list,
1085 rtx_timeout, gfp))
1086 return;
1087 /* We may have switched current transport */
1088 transport = *_transport;
1089 packet = &transport->packet;
1090 }
1109 1091
1110 if (sctp_outq_select_transport(chunk, asoc, _transport, 1092 /* Apply Max.Burst limitation to the current transport in
1111 transport_list)) { 1093 * case it will be used for new data. We are going to
1112 transport = *_transport; 1094 * rest it before we return, but we want to apply the limit
1113 packet = &transport->packet; 1095 * to the currently queued data.
1114 } 1096 */
1097 if (transport)
1098 sctp_transport_burst_limited(transport);
1115 1099
1116 pr_debug("%s: outq:%p, chunk:%p[%s], tx-tsn:0x%x skb->head:%p " 1100 /* Finally, transmit new packets. */
1117 "skb->users:%d\n", 1101 while ((chunk = sctp_outq_dequeue_data(q)) != NULL) {
1118 __func__, q, chunk, chunk && chunk->chunk_hdr ? 1102 __u32 sid = ntohs(chunk->subh.data_hdr->stream);
1119 sctp_cname(SCTP_ST_CHUNK(chunk->chunk_hdr->type)) :
1120 "illegal chunk", ntohl(chunk->subh.data_hdr->tsn),
1121 chunk->skb ? chunk->skb->head : NULL, chunk->skb ?
1122 refcount_read(&chunk->skb->users) : -1);
1123
1124 /* Add the chunk to the packet. */
1125 status = sctp_packet_transmit_chunk(packet, chunk, 0, gfp);
1126 switch (status) {
1127 case SCTP_XMIT_OK:
1128 break;
1129 1103
1130 case SCTP_XMIT_PMTU_FULL: 1104 /* Has this chunk expired? */
1131 case SCTP_XMIT_RWND_FULL: 1105 if (sctp_chunk_abandoned(chunk)) {
1132 case SCTP_XMIT_DELAY: 1106 sctp_sched_dequeue_done(q, chunk);
1133 /* We could not append this chunk, so put 1107 sctp_chunk_fail(chunk, 0);
1134 * the chunk back on the output queue. 1108 sctp_chunk_free(chunk);
1135 */ 1109 continue;
1136 pr_debug("%s: could not transmit tsn:0x%x, status:%d\n", 1110 }
1137 __func__, ntohl(chunk->subh.data_hdr->tsn),
1138 status);
1139 1111
1140 sctp_outq_head_data(q, chunk); 1112 if (asoc->stream.out[sid].state == SCTP_STREAM_CLOSED) {
1141 return; 1113 sctp_outq_head_data(q, chunk);
1142 } 1114 break;
1115 }
1143 1116
1144 /* The sender is in the SHUTDOWN-PENDING state, 1117 if (sctp_outq_select_transport(chunk, asoc, _transport,
1145 * The sender MAY set the I-bit in the DATA 1118 transport_list)) {
1146 * chunk header. 1119 transport = *_transport;
1147 */ 1120 packet = &transport->packet;
1148 if (asoc->state == SCTP_STATE_SHUTDOWN_PENDING) 1121 }
1149 chunk->chunk_hdr->flags |= SCTP_DATA_SACK_IMM;
1150 if (chunk->chunk_hdr->flags & SCTP_DATA_UNORDERED)
1151 asoc->stats.ouodchunks++;
1152 else
1153 asoc->stats.oodchunks++;
1154 1122
1155 /* Only now it's safe to consider this 1123 pr_debug("%s: outq:%p, chunk:%p[%s], tx-tsn:0x%x skb->head:%p "
1156 * chunk as sent, sched-wise. 1124 "skb->users:%d\n",
1125 __func__, q, chunk, chunk && chunk->chunk_hdr ?
1126 sctp_cname(SCTP_ST_CHUNK(chunk->chunk_hdr->type)) :
1127 "illegal chunk", ntohl(chunk->subh.data_hdr->tsn),
1128 chunk->skb ? chunk->skb->head : NULL, chunk->skb ?
1129 refcount_read(&chunk->skb->users) : -1);
1130
1131 /* Add the chunk to the packet. */
1132 status = sctp_packet_transmit_chunk(packet, chunk, 0, gfp);
1133 if (status != SCTP_XMIT_OK) {
1134 /* We could not append this chunk, so put
1135 * the chunk back on the output queue.
1157 */ 1136 */
1158 sctp_sched_dequeue_done(q, chunk); 1137 pr_debug("%s: could not transmit tsn:0x%x, status:%d\n",
1138 __func__, ntohl(chunk->subh.data_hdr->tsn),
1139 status);
1159 1140
1160 list_add_tail(&chunk->transmitted_list, 1141 sctp_outq_head_data(q, chunk);
1161 &transport->transmitted); 1142 break;
1143 }
1162 1144
1163 sctp_transport_reset_t3_rtx(transport); 1145 /* The sender is in the SHUTDOWN-PENDING state,
1164 transport->last_time_sent = jiffies; 1146 * The sender MAY set the I-bit in the DATA
1147 * chunk header.
1148 */
1149 if (asoc->state == SCTP_STATE_SHUTDOWN_PENDING)
1150 chunk->chunk_hdr->flags |= SCTP_DATA_SACK_IMM;
1151 if (chunk->chunk_hdr->flags & SCTP_DATA_UNORDERED)
1152 asoc->stats.ouodchunks++;
1153 else
1154 asoc->stats.oodchunks++;
1165 1155
1166 /* Only let one DATA chunk get bundled with a 1156 /* Only now it's safe to consider this
1167 * COOKIE-ECHO chunk. 1157 * chunk as sent, sched-wise.
1168 */ 1158 */
1169 if (packet->has_cookie_echo) 1159 sctp_sched_dequeue_done(q, chunk);
1170 break;
1171 }
1172 break;
1173 1160
1174 default: 1161 list_add_tail(&chunk->transmitted_list,
1175 /* Do nothing. */ 1162 &transport->transmitted);
1176 break; 1163
1164 sctp_transport_reset_t3_rtx(transport);
1165 transport->last_time_sent = jiffies;
1166
1167 /* Only let one DATA chunk get bundled with a
1168 * COOKIE-ECHO chunk.
1169 */
1170 if (packet->has_cookie_echo)
1171 break;
1177 } 1172 }
1178} 1173}
1179 1174