Skip to content

Commit 1ce463d

Browse files
committed
Merge branch 'sctp-sender-side-stream-reconf-ssn-reset-request-chunk'
Xin Long says: ==================== sctp: add sender-side procedures for stream reconf ssn reset request chunk Patch 6/6 is to implement sender-side procedures for the Outgoing and Incoming SSN Reset Request Parameter described in rfc6525 section 5.1.2 and 5.1.3 Patches 1-5/6 are ahead of it to define some apis and asoc members for it. Note that with this patchset, asoc->reconf_enable has no chance yet to be set, until the patch "sctp: add get and set sockopt for reconf_enable" is applied in the future. As we can not just enable it when sctp is not capable of processing reconf chunk yet. v1->v2: - put these into a smaller group. - rename some temporary variables in the codes. - rename the titles of the commits and improve some changelogs. v2->v3: - re-split the patchset and make sure it has no dead codes for review. v3->v4: - move sctp_make_reconf() into patch 1/6 to avoid kbuild warning. - drop unused struct sctp_strreset_req. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents b16ed2b + 7f9d68a commit 1ce463d

File tree

19 files changed

+583
-16
lines changed

19 files changed

+583
-16
lines changed

include/linux/sctp.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ typedef enum {
108108
/* Use hex, as defined in ADDIP sec. 3.1 */
109109
SCTP_CID_ASCONF = 0xC1,
110110
SCTP_CID_ASCONF_ACK = 0x80,
111+
SCTP_CID_RECONF = 0x82,
111112
} sctp_cid_t; /* enum */
112113

113114

@@ -199,6 +200,13 @@ typedef enum {
199200
SCTP_PARAM_SUCCESS_REPORT = cpu_to_be16(0xc005),
200201
SCTP_PARAM_ADAPTATION_LAYER_IND = cpu_to_be16(0xc006),
201202

203+
/* RE-CONFIG. Section 4 */
204+
SCTP_PARAM_RESET_OUT_REQUEST = cpu_to_be16(0x000d),
205+
SCTP_PARAM_RESET_IN_REQUEST = cpu_to_be16(0x000e),
206+
SCTP_PARAM_RESET_TSN_REQUEST = cpu_to_be16(0x000f),
207+
SCTP_PARAM_RESET_RESPONSE = cpu_to_be16(0x0010),
208+
SCTP_PARAM_RESET_ADD_OUT_STREAMS = cpu_to_be16(0x0011),
209+
SCTP_PARAM_RESET_ADD_IN_STREAMS = cpu_to_be16(0x0012),
202210
} sctp_param_t; /* enum */
203211

204212

@@ -710,4 +718,23 @@ struct sctp_infox {
710718
struct sctp_association *asoc;
711719
};
712720

721+
struct sctp_reconf_chunk {
722+
sctp_chunkhdr_t chunk_hdr;
723+
__u8 params[0];
724+
} __packed;
725+
726+
struct sctp_strreset_outreq {
727+
sctp_paramhdr_t param_hdr;
728+
__u32 request_seq;
729+
__u32 response_seq;
730+
__u32 send_reset_at_tsn;
731+
__u16 list_of_streams[0];
732+
} __packed;
733+
734+
struct sctp_strreset_inreq {
735+
sctp_paramhdr_t param_hdr;
736+
__u32 request_seq;
737+
__u16 list_of_streams[0];
738+
} __packed;
739+
713740
#endif /* __LINUX_SCTP_H__ */

include/net/netns/sctp.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,9 @@ struct netns_sctp {
118118
/* Flag to indicate if PR-SCTP is enabled. */
119119
int prsctp_enable;
120120

121+
/* Flag to indicate if PR-CONFIG is enabled. */
122+
int reconf_enable;
123+
121124
/* Flag to idicate if SCTP-AUTH is enabled */
122125
int auth_enable;
123126

include/net/sctp/constants.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ typedef enum {
9090
SCTP_EVENT_TIMEOUT_T4_RTO,
9191
SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD,
9292
SCTP_EVENT_TIMEOUT_HEARTBEAT,
93+
SCTP_EVENT_TIMEOUT_RECONF,
9394
SCTP_EVENT_TIMEOUT_SACK,
9495
SCTP_EVENT_TIMEOUT_AUTOCLOSE,
9596
} sctp_event_timeout_t;
@@ -113,9 +114,10 @@ typedef enum {
113114
SCTP_PRIMITIVE_SEND,
114115
SCTP_PRIMITIVE_REQUESTHEARTBEAT,
115116
SCTP_PRIMITIVE_ASCONF,
117+
SCTP_PRIMITIVE_RECONF,
116118
} sctp_event_primitive_t;
117119

118-
#define SCTP_EVENT_PRIMITIVE_MAX SCTP_PRIMITIVE_ASCONF
120+
#define SCTP_EVENT_PRIMITIVE_MAX SCTP_PRIMITIVE_RECONF
119121
#define SCTP_NUM_PRIMITIVE_TYPES (SCTP_EVENT_PRIMITIVE_MAX + 1)
120122

121123
/* We define here a utility type for manipulating subtypes.

include/net/sctp/sctp.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,8 @@ int sctp_primitive_ABORT(struct net *, struct sctp_association *, void *arg);
141141
int sctp_primitive_SEND(struct net *, struct sctp_association *, void *arg);
142142
int sctp_primitive_REQUESTHEARTBEAT(struct net *, struct sctp_association *, void *arg);
143143
int sctp_primitive_ASCONF(struct net *, struct sctp_association *, void *arg);
144+
int sctp_primitive_RECONF(struct net *net, struct sctp_association *asoc,
145+
void *arg);
144146

145147
/*
146148
* sctp/input.c
@@ -191,6 +193,12 @@ void sctp_remaddr_proc_exit(struct net *net);
191193
*/
192194
int sctp_offload_init(void);
193195

196+
/*
197+
* sctp/stream.c
198+
*/
199+
int sctp_send_reset_streams(struct sctp_association *asoc,
200+
struct sctp_reset_streams *params);
201+
194202
/*
195203
* Module global variables
196204
*/

include/net/sctp/sm.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ sctp_state_fn_t sctp_sf_error_shutdown;
157157
sctp_state_fn_t sctp_sf_ignore_primitive;
158158
sctp_state_fn_t sctp_sf_do_prm_requestheartbeat;
159159
sctp_state_fn_t sctp_sf_do_prm_asconf;
160+
sctp_state_fn_t sctp_sf_do_prm_reconf;
160161

161162
/* Prototypes for other event state functions. */
162163
sctp_state_fn_t sctp_sf_do_no_pending_tsn;
@@ -167,6 +168,7 @@ sctp_state_fn_t sctp_sf_cookie_wait_icmp_abort;
167168

168169
/* Prototypes for timeout event state functions. */
169170
sctp_state_fn_t sctp_sf_do_6_3_3_rtx;
171+
sctp_state_fn_t sctp_sf_send_reconf;
170172
sctp_state_fn_t sctp_sf_do_6_2_sack;
171173
sctp_state_fn_t sctp_sf_autoclose_timer_expire;
172174

@@ -259,7 +261,10 @@ struct sctp_chunk *sctp_make_fwdtsn(const struct sctp_association *asoc,
259261
__u32 new_cum_tsn, size_t nstreams,
260262
struct sctp_fwdtsn_skip *skiplist);
261263
struct sctp_chunk *sctp_make_auth(const struct sctp_association *asoc);
262-
264+
struct sctp_chunk *sctp_make_strreset_req(
265+
const struct sctp_association *asoc,
266+
__u16 stream_num, __u16 *stream_list,
267+
bool out, bool in);
263268
void sctp_chunk_assign_tsn(struct sctp_chunk *);
264269
void sctp_chunk_assign_ssn(struct sctp_chunk *);
265270

@@ -275,6 +280,7 @@ int sctp_do_sm(struct net *net, sctp_event_t event_type, sctp_subtype_t subtype,
275280
/* 2nd level prototypes */
276281
void sctp_generate_t3_rtx_event(unsigned long peer);
277282
void sctp_generate_heartbeat_event(unsigned long peer);
283+
void sctp_generate_reconf_event(unsigned long peer);
278284
void sctp_generate_proto_unreach_event(unsigned long peer);
279285

280286
void sctp_ootb_pkt_free(struct sctp_packet *);

include/net/sctp/structs.h

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -877,6 +877,9 @@ struct sctp_transport {
877877
/* Timer to handle ICMP proto unreachable envets */
878878
struct timer_list proto_unreach_timer;
879879

880+
/* Timer to handler reconf chunk rtx */
881+
struct timer_list reconf_timer;
882+
880883
/* Since we're using per-destination retransmission timers
881884
* (see above), we're also using per-destination "transmitted"
882885
* queues. This probably ought to be a private struct
@@ -935,6 +938,7 @@ void sctp_transport_pmtu(struct sctp_transport *, struct sock *sk);
935938
void sctp_transport_free(struct sctp_transport *);
936939
void sctp_transport_reset_t3_rtx(struct sctp_transport *);
937940
void sctp_transport_reset_hb_timer(struct sctp_transport *);
941+
void sctp_transport_reset_reconf_timer(struct sctp_transport *transport);
938942
int sctp_transport_hold(struct sctp_transport *);
939943
void sctp_transport_put(struct sctp_transport *);
940944
void sctp_transport_update_rto(struct sctp_transport *, __u32);
@@ -1251,7 +1255,10 @@ struct sctp_endpoint {
12511255
struct list_head endpoint_shared_keys;
12521256
__u16 active_key_id;
12531257
__u8 auth_enable:1,
1254-
prsctp_enable:1;
1258+
prsctp_enable:1,
1259+
reconf_enable:1;
1260+
1261+
__u8 strreset_enable;
12551262
};
12561263

12571264
/* Recover the outter endpoint structure. */
@@ -1504,6 +1511,7 @@ struct sctp_association {
15041511
hostname_address:1, /* Peer understands DNS addresses? */
15051512
asconf_capable:1, /* Does peer support ADDIP? */
15061513
prsctp_capable:1, /* Can peer do PR-SCTP? */
1514+
reconf_capable:1, /* Can peer do RE-CONFIG? */
15071515
auth_capable:1; /* Is peer doing SCTP-AUTH? */
15081516

15091517
/* sack_needed : This flag indicates if the next received
@@ -1863,7 +1871,16 @@ struct sctp_association {
18631871

18641872
__u8 need_ecne:1, /* Need to send an ECNE Chunk? */
18651873
temp:1, /* Is it a temporary association? */
1866-
prsctp_enable:1;
1874+
prsctp_enable:1,
1875+
reconf_enable:1;
1876+
1877+
__u8 strreset_enable;
1878+
__u8 strreset_outstanding; /* request param count on the fly */
1879+
1880+
__u32 strreset_outseq; /* Update after receiving response */
1881+
__u32 strreset_inseq; /* Update after receiving request */
1882+
1883+
struct sctp_chunk *strreset_chunk; /* save request chunk */
18671884

18681885
struct sctp_priv_assoc_stats stats;
18691886

include/uapi/linux/sctp.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,8 @@ typedef __s32 sctp_assoc_t;
115115
#define SCTP_PR_SUPPORTED 113
116116
#define SCTP_DEFAULT_PRINFO 114
117117
#define SCTP_PR_ASSOC_STATUS 115
118+
#define SCTP_ENABLE_STREAM_RESET 118
119+
#define SCTP_RESET_STREAMS 119
118120

119121
/* PR-SCTP policies */
120122
#define SCTP_PR_SCTP_NONE 0x0000
@@ -138,6 +140,15 @@ typedef __s32 sctp_assoc_t;
138140
#define SCTP_PR_RTX_ENABLED(x) (SCTP_PR_POLICY(x) == SCTP_PR_SCTP_RTX)
139141
#define SCTP_PR_PRIO_ENABLED(x) (SCTP_PR_POLICY(x) == SCTP_PR_SCTP_PRIO)
140142

143+
/* For enable stream reset */
144+
#define SCTP_ENABLE_RESET_STREAM_REQ 0x01
145+
#define SCTP_ENABLE_RESET_ASSOC_REQ 0x02
146+
#define SCTP_ENABLE_CHANGE_ASSOC_REQ 0x04
147+
#define SCTP_ENABLE_STRRESET_MASK 0x07
148+
149+
#define SCTP_STREAM_RESET_INCOMING 0x01
150+
#define SCTP_STREAM_RESET_OUTGOING 0x02
151+
141152
/* These are bit fields for msghdr->msg_flags. See section 5.1. */
142153
/* On user space Linux, these live in <bits/socket.h> as an enum. */
143154
enum sctp_msg_flags {
@@ -1008,4 +1019,11 @@ struct sctp_info {
10081019
__u32 __reserved3;
10091020
};
10101021

1022+
struct sctp_reset_streams {
1023+
sctp_assoc_t srs_assoc_id;
1024+
uint16_t srs_flags;
1025+
uint16_t srs_number_streams; /* 0 == ALL */
1026+
uint16_t srs_stream_list[]; /* list if srs_num_streams is not 0 */
1027+
};
1028+
10111029
#endif /* _UAPI_SCTP_H */

net/sctp/associola.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a
207207
* association to the same value as the initial TSN.
208208
*/
209209
asoc->addip_serial = asoc->c.initial_tsn;
210+
asoc->strreset_outseq = asoc->c.initial_tsn;
210211

211212
INIT_LIST_HEAD(&asoc->addip_chunk_list);
212213
INIT_LIST_HEAD(&asoc->asconf_ack_list);
@@ -269,6 +270,8 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a
269270

270271
asoc->active_key_id = ep->active_key_id;
271272
asoc->prsctp_enable = ep->prsctp_enable;
273+
asoc->reconf_enable = ep->reconf_enable;
274+
asoc->strreset_enable = ep->strreset_enable;
272275

273276
/* Save the hmacs and chunks list into this association */
274277
if (ep->auth_hmacs_list)
@@ -361,6 +364,9 @@ void sctp_association_free(struct sctp_association *asoc)
361364
/* Free stream information. */
362365
sctp_stream_free(asoc->stream);
363366

367+
if (asoc->strreset_chunk)
368+
sctp_chunk_free(asoc->strreset_chunk);
369+
364370
/* Clean up the bound address list. */
365371
sctp_bind_addr_free(&asoc->base.bind_addr);
366372

@@ -519,6 +525,12 @@ void sctp_assoc_rm_peer(struct sctp_association *asoc,
519525
if (asoc->peer.last_data_from == peer)
520526
asoc->peer.last_data_from = transport;
521527

528+
if (asoc->strreset_chunk &&
529+
asoc->strreset_chunk->transport == peer) {
530+
asoc->strreset_chunk->transport = transport;
531+
sctp_transport_reset_reconf_timer(transport);
532+
}
533+
522534
/* If we remove the transport an INIT was last sent to, set it to
523535
* NULL. Combined with the update of the retran path above, this
524536
* will cause the next INIT to be sent to the next available

net/sctp/endpointola.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep,
164164
ep->auth_hmacs_list = auth_hmacs;
165165
ep->auth_chunk_list = auth_chunks;
166166
ep->prsctp_enable = net->sctp.prsctp_enable;
167+
ep->reconf_enable = net->sctp.reconf_enable;
167168

168169
return ep;
169170

net/sctp/outqueue.c

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -915,22 +915,28 @@ static void sctp_outq_flush(struct sctp_outq *q, int rtx_timeout, gfp_t gfp)
915915
case SCTP_CID_ECN_ECNE:
916916
case SCTP_CID_ASCONF:
917917
case SCTP_CID_FWD_TSN:
918+
case SCTP_CID_RECONF:
918919
status = sctp_packet_transmit_chunk(packet, chunk,
919920
one_packet, gfp);
920921
if (status != SCTP_XMIT_OK) {
921922
/* put the chunk back */
922923
list_add(&chunk->list, &q->control_chunk_list);
923-
} else {
924-
asoc->stats.octrlchunks++;
925-
/* PR-SCTP C5) If a FORWARD TSN is sent, the
926-
* sender MUST assure that at least one T3-rtx
927-
* timer is running.
928-
*/
929-
if (chunk->chunk_hdr->type == SCTP_CID_FWD_TSN) {
930-
sctp_transport_reset_t3_rtx(transport);
931-
transport->last_time_sent = jiffies;
932-
}
924+
break;
925+
}
926+
927+
asoc->stats.octrlchunks++;
928+
/* PR-SCTP C5) If a FORWARD TSN is sent, the
929+
* sender MUST assure that at least one T3-rtx
930+
* timer is running.
931+
*/
932+
if (chunk->chunk_hdr->type == SCTP_CID_FWD_TSN) {
933+
sctp_transport_reset_t3_rtx(transport);
934+
transport->last_time_sent = jiffies;
933935
}
936+
937+
if (chunk == asoc->strreset_chunk)
938+
sctp_transport_reset_reconf_timer(transport);
939+
934940
break;
935941

936942
default:
@@ -1016,6 +1022,8 @@ static void sctp_outq_flush(struct sctp_outq *q, int rtx_timeout, gfp_t gfp)
10161022

10171023
/* Finally, transmit new packets. */
10181024
while ((chunk = sctp_outq_dequeue_data(q)) != NULL) {
1025+
__u32 sid = ntohs(chunk->subh.data_hdr->stream);
1026+
10191027
/* RFC 2960 6.5 Every DATA chunk MUST carry a valid
10201028
* stream identifier.
10211029
*/
@@ -1038,6 +1046,11 @@ static void sctp_outq_flush(struct sctp_outq *q, int rtx_timeout, gfp_t gfp)
10381046
continue;
10391047
}
10401048

1049+
if (asoc->stream->out[sid].state == SCTP_STREAM_CLOSED) {
1050+
sctp_outq_head_data(q, chunk);
1051+
goto sctp_flush_out;
1052+
}
1053+
10411054
/* If there is a specified transport, use it.
10421055
* Otherwise, we want to use the active path.
10431056
*/

net/sctp/primitive.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,3 +211,6 @@ DECLARE_PRIMITIVE(REQUESTHEARTBEAT);
211211
*/
212212

213213
DECLARE_PRIMITIVE(ASCONF);
214+
215+
/* RE-CONFIG 5.1 */
216+
DECLARE_PRIMITIVE(RECONF);

net/sctp/protocol.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1258,6 +1258,9 @@ static int __net_init sctp_defaults_init(struct net *net)
12581258
/* Enable PR-SCTP by default. */
12591259
net->sctp.prsctp_enable = 1;
12601260

1261+
/* Disable RECONF by default. */
1262+
net->sctp.reconf_enable = 0;
1263+
12611264
/* Disable AUTH by default. */
12621265
net->sctp.auth_enable = 0;
12631266

0 commit comments

Comments
 (0)