kill tsol ("Trusted Solaris") aka TX ("Trusted Extensions")
[unleashed.git] / kernel / net / sctp / sctp_shutdown.c
blob1c1ea7d432a65c6b06b842839e5b01da8658bff7
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
23 * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
26 #include <sys/types.h>
27 #include <sys/systm.h>
28 #include <sys/stream.h>
29 #include <sys/ddi.h>
30 #include <sys/sunddi.h>
31 #include <sys/strsubr.h>
32 #include <sys/strsun.h>
34 #include <netinet/in.h>
35 #include <netinet/ip6.h>
37 #include <inet/ipsec_impl.h>
38 #include <inet/common.h>
39 #include <inet/ip.h>
40 #include <inet/ip6.h>
41 #include <inet/mib2.h>
42 #include <inet/nd.h>
43 #include <inet/optcom.h>
44 #include <inet/sctp_ip.h>
45 #include <inet/ipclassifier.h>
46 #include <inet/sctp/sctp_impl.h>
48 void
49 sctp_send_shutdown(sctp_t *sctp, int rexmit)
51 mblk_t *smp;
52 mblk_t *sendmp;
53 sctp_chunk_hdr_t *sch;
54 uint32_t *ctsn;
55 sctp_faddr_t *fp;
56 sctp_stack_t *sctps = sctp->sctp_sctps;
58 if (sctp->sctp_state != SCTPS_ESTABLISHED &&
59 sctp->sctp_state != SCTPS_SHUTDOWN_PENDING &&
60 sctp->sctp_state != SCTPS_SHUTDOWN_SENT) {
61 return;
64 if (sctp->sctp_state == SCTPS_ESTABLISHED) {
65 sctp->sctp_state = SCTPS_SHUTDOWN_PENDING;
67 * We set an upper bound on how long we will
68 * wait for a shutdown-ack from the peer. This
69 * is to prevent the receiver from attempting
70 * to create a half-closed state indefinately.
71 * See archive from IETF TSVWG mailing list
72 * for June 2001 for more information.
73 * Since we will not be calculating RTTs after
74 * sending the shutdown, we can overload out_time
75 * to track how long we have waited.
77 sctp->sctp_out_time = ddi_get_lbolt64();
81 * If there is unsent (or unacked) data, wait for it to get ack'd
83 if (sctp->sctp_xmit_head != NULL || sctp->sctp_xmit_unsent != NULL) {
84 return;
87 /* rotate faddrs if we are retransmitting */
88 if (!rexmit) {
89 fp = sctp->sctp_current;
90 } else {
91 fp = sctp_rotate_faddr(sctp, sctp->sctp_shutdown_faddr);
94 sctp->sctp_shutdown_faddr = fp;
96 /* Link in a SACK if resending the shutdown */
97 if (sctp->sctp_state > SCTPS_SHUTDOWN_PENDING &&
98 (sendmp = sctp_make_sack(sctp, fp, NULL)) != NULL) {
100 smp = allocb(sizeof (*sch) + sizeof (*ctsn), BPRI_MED);
101 if (smp == NULL) {
102 freemsg(sendmp);
103 goto done;
105 linkb(sendmp, smp);
107 sch = (sctp_chunk_hdr_t *)smp->b_rptr;
108 smp->b_wptr = smp->b_rptr + sizeof (*sch) + sizeof (*ctsn);
109 } else {
110 sendmp = sctp_make_mp(sctp, fp,
111 sizeof (*sch) + sizeof (*ctsn));
112 if (sendmp == NULL) {
113 SCTP_KSTAT(sctps, sctp_send_shutdown_failed);
114 goto done;
116 sch = (sctp_chunk_hdr_t *)sendmp->b_wptr;
117 sendmp->b_wptr += sizeof (*sch) + sizeof (*ctsn);
119 /* shutdown w/o sack, update lastacked */
120 sctp->sctp_lastacked = sctp->sctp_ftsn - 1;
123 sch->sch_id = CHUNK_SHUTDOWN;
124 sch->sch_flags = 0;
125 sch->sch_len = htons(sizeof (*sch) + sizeof (*ctsn));
127 ctsn = (uint32_t *)(sch + 1);
128 *ctsn = htonl(sctp->sctp_lastacked);
130 /* Link the shutdown chunk in after the IP/SCTP header */
132 BUMP_LOCAL(sctp->sctp_obchunks);
134 /* Send the shutdown and restart the timer */
135 sctp_set_iplen(sctp, sendmp, fp->sf_ixa);
136 (void) conn_ip_output(sendmp, fp->sf_ixa);
137 BUMP_LOCAL(sctp->sctp_opkts);
139 done:
140 sctp->sctp_state = SCTPS_SHUTDOWN_SENT;
141 SCTP_FADDR_TIMER_RESTART(sctp, sctp->sctp_current,
142 sctp->sctp_current->sf_rto);
146 sctp_shutdown_received(sctp_t *sctp, sctp_chunk_hdr_t *sch, boolean_t crwsd,
147 boolean_t rexmit, sctp_faddr_t *fp)
149 mblk_t *samp;
150 uint32_t *tsn;
151 int trysend = 0;
153 if (sctp->sctp_state != SCTPS_SHUTDOWN_ACK_SENT)
154 sctp->sctp_state = SCTPS_SHUTDOWN_RECEIVED;
156 /* Extract and process the TSN in the shutdown chunk */
157 if (sch != NULL) {
158 tsn = (uint32_t *)(sch + 1);
159 /* not already acked */
160 if (!SEQ_LT(ntohl(*tsn), sctp->sctp_lastack_rxd))
161 trysend = sctp_cumack(sctp, ntohl(*tsn), &samp);
164 /* Don't allow sending new data */
165 if (!SCTP_IS_DETACHED(sctp) && !sctp->sctp_ulp_discon_done) {
166 sctp->sctp_ulp_opctl(sctp->sctp_ulpd, SOCK_OPCTL_SHUT_SEND, 0);
167 sctp->sctp_ulp_discon_done = B_TRUE;
171 * If there is unsent or unacked data, try sending them out now.
172 * The other side should acknowledge them. After we have flushed
173 * the transmit queue, we can complete the shutdown sequence.
175 if (sctp->sctp_xmit_head != NULL || sctp->sctp_xmit_unsent != NULL)
176 return (1);
178 if (fp == NULL) {
179 /* rotate faddrs if we are retransmitting */
180 if (!rexmit)
181 fp = sctp->sctp_current;
182 else
183 fp = sctp_rotate_faddr(sctp, sctp->sctp_shutdown_faddr);
186 sctp_send_shutdown_ack(sctp, fp, crwsd);
188 return (trysend);
191 void
192 sctp_shutdown_complete(sctp_t *sctp)
194 mblk_t *scmp;
195 sctp_chunk_hdr_t *scch;
196 sctp_stack_t *sctps = sctp->sctp_sctps;
198 scmp = sctp_make_mp(sctp, sctp->sctp_current, sizeof (*scch));
199 if (scmp == NULL) {
200 /* XXX use timer approach */
201 SCTP_KSTAT(sctps, sctp_send_shutdown_comp_failed);
202 return;
205 scch = (sctp_chunk_hdr_t *)scmp->b_wptr;
206 scch->sch_id = CHUNK_SHUTDOWN_COMPLETE;
207 scch->sch_flags = 0;
208 scch->sch_len = htons(sizeof (*scch));
210 scmp->b_wptr += sizeof (*scch);
212 BUMP_LOCAL(sctp->sctp_obchunks);
214 sctp_set_iplen(sctp, scmp, sctp->sctp_current->sf_ixa);
215 (void) conn_ip_output(scmp, sctp->sctp_current->sf_ixa);
216 BUMP_LOCAL(sctp->sctp_opkts);
220 * Similar to sctp_shutdown_complete(), except that since this
221 * is out-of-the-blue, we can't use an sctp's association information,
222 * and instead must draw all necessary info from the incoming packet.
224 void
225 sctp_ootb_shutdown_ack(mblk_t *mp, uint_t ip_hdr_len, ip_recv_attr_t *ira,
226 ip_stack_t *ipst)
228 boolean_t isv4;
229 ipha_t *ipha = NULL;
230 ip6_t *ip6h = NULL;
231 sctp_hdr_t *insctph;
232 sctp_chunk_hdr_t *scch;
233 int i;
234 uint16_t port;
235 mblk_t *mp1;
236 netstack_t *ns = ipst->ips_netstack;
237 sctp_stack_t *sctps = ns->netstack_sctp;
238 ip_xmit_attr_t ixas;
240 bzero(&ixas, sizeof (ixas));
242 isv4 = (IPH_HDR_VERSION(mp->b_rptr) == IPV4_VERSION);
244 ASSERT(MBLKL(mp) >= sizeof (*insctph) + sizeof (*scch) +
245 (isv4 ? sizeof (ipha_t) : sizeof (ip6_t)));
248 * Check to see if we can reuse the incoming mblk. There should
249 * not be other reference. Since this packet comes from below,
250 * there should be enough header space to fill in what the lower
251 * layers want to add.
253 if (DB_REF(mp) != 1) {
254 mp1 = allocb(MBLKL(mp) + sctps->sctps_wroff_xtra, BPRI_MED);
255 if (mp1 == NULL) {
256 freeb(mp);
257 return;
259 mp1->b_rptr += sctps->sctps_wroff_xtra;
260 bcopy(mp->b_rptr, mp1->b_rptr, MBLKL(mp));
261 freeb(mp);
262 mp = mp1;
263 } else {
264 DB_CKSUMFLAGS(mp) = 0;
267 ixas.ixa_pktlen = ip_hdr_len + sizeof (*insctph) + sizeof (*scch);
268 ixas.ixa_ip_hdr_length = ip_hdr_len;
269 mp->b_wptr = (mp->b_rptr + ixas.ixa_pktlen);
272 * We follow the logic in tcp_xmit_early_reset() in that we skip
273 * reversing source route (i.e. replace all IP options with EOL).
275 if (isv4) {
276 ipaddr_t v4addr;
278 ipha = (ipha_t *)mp->b_rptr;
279 for (i = IP_SIMPLE_HDR_LENGTH; i < (int)ip_hdr_len; i++)
280 mp->b_rptr[i] = IPOPT_EOL;
281 /* Swap addresses */
282 ipha->ipha_length = htons(ixas.ixa_pktlen);
283 v4addr = ipha->ipha_src;
284 ipha->ipha_src = ipha->ipha_dst;
285 ipha->ipha_dst = v4addr;
286 ipha->ipha_ident = 0;
287 ipha->ipha_ttl = (uchar_t)sctps->sctps_ipv4_ttl;
289 ixas.ixa_flags = IXAF_BASIC_SIMPLE_V4;
290 } else {
291 in6_addr_t v6addr;
293 ip6h = (ip6_t *)mp->b_rptr;
294 /* Remove any extension headers assuming partial overlay */
295 if (ip_hdr_len > IPV6_HDR_LEN) {
296 uint8_t *to;
298 to = mp->b_rptr + ip_hdr_len - IPV6_HDR_LEN;
299 ovbcopy(ip6h, to, IPV6_HDR_LEN);
300 mp->b_rptr += ip_hdr_len - IPV6_HDR_LEN;
301 ip_hdr_len = IPV6_HDR_LEN;
302 ip6h = (ip6_t *)mp->b_rptr;
303 ip6h->ip6_nxt = IPPROTO_SCTP;
305 ip6h->ip6_plen = htons(ixas.ixa_pktlen - IPV6_HDR_LEN);
306 v6addr = ip6h->ip6_src;
307 ip6h->ip6_src = ip6h->ip6_dst;
308 ip6h->ip6_dst = v6addr;
309 ip6h->ip6_hops = (uchar_t)sctps->sctps_ipv6_hoplimit;
311 ixas.ixa_flags = IXAF_BASIC_SIMPLE_V6;
312 if (IN6_IS_ADDR_LINKSCOPE(&ip6h->ip6_dst)) {
313 ixas.ixa_flags |= IXAF_SCOPEID_SET;
314 ixas.ixa_scopeid = ira->ira_ruifindex;
318 insctph = (sctp_hdr_t *)(mp->b_rptr + ip_hdr_len);
320 /* Swap ports. Verification tag is reused. */
321 port = insctph->sh_sport;
322 insctph->sh_sport = insctph->sh_dport;
323 insctph->sh_dport = port;
325 /* Lay in the shutdown complete chunk */
326 scch = (sctp_chunk_hdr_t *)(insctph + 1);
327 scch->sch_id = CHUNK_SHUTDOWN_COMPLETE;
328 scch->sch_len = htons(sizeof (*scch));
329 scch->sch_flags = 0;
331 /* Set the T-bit */
332 SCTP_SET_TBIT(scch);
334 ixas.ixa_protocol = IPPROTO_SCTP;
335 ixas.ixa_zoneid = ira->ira_zoneid;
336 ixas.ixa_ipst = ipst;
337 ixas.ixa_ifindex = 0;
339 if (ira->ira_flags & IRAF_IPSEC_SECURE) {
341 * Apply IPsec based on how IPsec was applied to
342 * the packet that was out of the blue.
344 if (!ipsec_in_to_out(ira, &ixas, mp, ipha, ip6h)) {
345 BUMP_MIB(&ipst->ips_ip_mib, ipIfStatsOutDiscards);
346 /* Note: mp already consumed and ip_drop_packet done */
347 return;
349 } else {
351 * This is in clear. The message we are building
352 * here should go out in clear, independent of our policy.
354 ixas.ixa_flags |= IXAF_NO_IPSEC;
357 (void) ip_output_simple(mp, &ixas);
358 ixa_cleanup(&ixas);
362 * Called from sctp_input_data() and sctp_shutdown_received().
363 * Send a SHUTDOWN ACK chunk to the peer SCTP endpoint and change SCTP state.
364 * This should be done after all data (unacked and unsend) has been
365 * acknowledged.
367 void
368 sctp_send_shutdown_ack(sctp_t *sctp, sctp_faddr_t *fp, boolean_t crwsd)
370 mblk_t *samp;
371 sctp_chunk_hdr_t *sach;
372 sctp_stack_t *sctps = sctp->sctp_sctps;
374 ASSERT(sctp->sctp_xmit_unacked == NULL);
375 ASSERT(sctp->sctp_lastack_rxd == (sctp->sctp_ltsn - 1));
376 ASSERT(fp != NULL);
378 sctp->sctp_shutdown_faddr = fp;
380 samp = sctp_make_mp(sctp, fp, sizeof (*sach));
381 if (samp == NULL) {
382 SCTP_KSTAT(sctps, sctp_send_shutdown_ack_failed);
383 goto dotimer;
386 sach = (sctp_chunk_hdr_t *)samp->b_wptr;
387 sach->sch_id = CHUNK_SHUTDOWN_ACK;
388 sach->sch_flags = 0;
389 sach->sch_len = htons(sizeof (*sach));
391 samp->b_wptr += sizeof (*sach);
393 * bundle a "cookie received while shutting down" error if
394 * the caller asks for it.
396 if (crwsd) {
397 mblk_t *errmp;
399 errmp = sctp_make_err(sctp, SCTP_ERR_COOKIE_SHUT, NULL, 0);
400 if (errmp != NULL) {
401 linkb(samp, errmp);
402 BUMP_LOCAL(sctp->sctp_obchunks);
406 BUMP_LOCAL(sctp->sctp_obchunks);
408 sctp_set_iplen(sctp, samp, fp->sf_ixa);
409 (void) conn_ip_output(samp, fp->sf_ixa);
410 BUMP_LOCAL(sctp->sctp_opkts);
412 dotimer:
413 sctp->sctp_state = SCTPS_SHUTDOWN_ACK_SENT;
414 SCTP_FADDR_TIMER_RESTART(sctp, fp, fp->sf_rto);