diff options
Diffstat (limited to 'net/sctp/outqueue.c')
-rw-r--r-- | net/sctp/outqueue.c | 27 |
1 files changed, 25 insertions, 2 deletions
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c index 23e5e97aa617..abfc0b8dee74 100644 --- a/net/sctp/outqueue.c +++ b/net/sctp/outqueue.c | |||
@@ -50,6 +50,7 @@ | |||
50 | #include <linux/list.h> /* For struct list_head */ | 50 | #include <linux/list.h> /* For struct list_head */ |
51 | #include <linux/socket.h> | 51 | #include <linux/socket.h> |
52 | #include <linux/ip.h> | 52 | #include <linux/ip.h> |
53 | #include <linux/slab.h> | ||
53 | #include <net/sock.h> /* For skb_set_owner_w */ | 54 | #include <net/sock.h> /* For skb_set_owner_w */ |
54 | 55 | ||
55 | #include <net/sctp/sctp.h> | 56 | #include <net/sctp/sctp.h> |
@@ -191,8 +192,8 @@ static inline int sctp_cacc_skip(struct sctp_transport *primary, | |||
191 | __u32 tsn) | 192 | __u32 tsn) |
192 | { | 193 | { |
193 | if (primary->cacc.changeover_active && | 194 | if (primary->cacc.changeover_active && |
194 | (sctp_cacc_skip_3_1(primary, transport, count_of_newacks) | 195 | (sctp_cacc_skip_3_1(primary, transport, count_of_newacks) || |
195 | || sctp_cacc_skip_3_2(primary, tsn))) | 196 | sctp_cacc_skip_3_2(primary, tsn))) |
196 | return 1; | 197 | return 1; |
197 | return 0; | 198 | return 0; |
198 | } | 199 | } |
@@ -921,6 +922,14 @@ static int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout) | |||
921 | goto sctp_flush_out; | 922 | goto sctp_flush_out; |
922 | } | 923 | } |
923 | 924 | ||
925 | /* Apply Max.Burst limitation to the current transport in | ||
926 | * case it will be used for new data. We are going to | ||
927 | * rest it before we return, but we want to apply the limit | ||
928 | * to the currently queued data. | ||
929 | */ | ||
930 | if (transport) | ||
931 | sctp_transport_burst_limited(transport); | ||
932 | |||
924 | /* Finally, transmit new packets. */ | 933 | /* Finally, transmit new packets. */ |
925 | while ((chunk = sctp_outq_dequeue_data(q)) != NULL) { | 934 | while ((chunk = sctp_outq_dequeue_data(q)) != NULL) { |
926 | /* RFC 2960 6.5 Every DATA chunk MUST carry a valid | 935 | /* RFC 2960 6.5 Every DATA chunk MUST carry a valid |
@@ -966,6 +975,10 @@ static int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout) | |||
966 | packet = &transport->packet; | 975 | packet = &transport->packet; |
967 | sctp_packet_config(packet, vtag, | 976 | sctp_packet_config(packet, vtag, |
968 | asoc->peer.ecn_capable); | 977 | asoc->peer.ecn_capable); |
978 | /* We've switched transports, so apply the | ||
979 | * Burst limit to the new transport. | ||
980 | */ | ||
981 | sctp_transport_burst_limited(transport); | ||
969 | } | 982 | } |
970 | 983 | ||
971 | SCTP_DEBUG_PRINTK("sctp_outq_flush(%p, %p[%s]), ", | 984 | SCTP_DEBUG_PRINTK("sctp_outq_flush(%p, %p[%s]), ", |
@@ -1001,6 +1014,13 @@ static int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout) | |||
1001 | break; | 1014 | break; |
1002 | 1015 | ||
1003 | case SCTP_XMIT_OK: | 1016 | case SCTP_XMIT_OK: |
1017 | /* The sender is in the SHUTDOWN-PENDING state, | ||
1018 | * The sender MAY set the I-bit in the DATA | ||
1019 | * chunk header. | ||
1020 | */ | ||
1021 | if (asoc->state == SCTP_STATE_SHUTDOWN_PENDING) | ||
1022 | chunk->chunk_hdr->flags |= SCTP_DATA_SACK_IMM; | ||
1023 | |||
1004 | break; | 1024 | break; |
1005 | 1025 | ||
1006 | default: | 1026 | default: |
@@ -1053,6 +1073,9 @@ sctp_flush_out: | |||
1053 | packet = &t->packet; | 1073 | packet = &t->packet; |
1054 | if (!sctp_packet_empty(packet)) | 1074 | if (!sctp_packet_empty(packet)) |
1055 | error = sctp_packet_transmit(packet); | 1075 | error = sctp_packet_transmit(packet); |
1076 | |||
1077 | /* Clear the burst limited state, if any */ | ||
1078 | sctp_transport_burst_reset(t); | ||
1056 | } | 1079 | } |
1057 | 1080 | ||
1058 | return error; | 1081 | return error; |