1 /* 2 * CDDL HEADER START 3 * 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. 7 * 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. 12 * 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] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #include <sys/types.h> 28 #include <sys/systm.h> 29 #include <sys/stream.h> 30 #include <sys/cmn_err.h> 31 #include <sys/kmem.h> 32 #define _SUN_TPI_VERSION 2 33 #include <sys/tihdr.h> 34 #include <sys/stropts.h> 35 #include <sys/strsubr.h> 36 #include <sys/socket.h> 37 #include <sys/tsol/tndb.h> 38 39 #include <netinet/in.h> 40 #include <netinet/ip6.h> 41 42 #include <inet/common.h> 43 #include <inet/ip.h> 44 #include <inet/ip6.h> 45 #include <inet/ipclassifier.h> 46 #include <inet/ipsec_impl.h> 47 48 #include "sctp_impl.h" 49 #include "sctp_addr.h" 50 51 /* 52 * Common accept code. Called by sctp_conn_request. 53 * cr_pkt is the INIT / INIT ACK packet. 54 */ 55 static int 56 sctp_accept_comm(sctp_t *listener, sctp_t *acceptor, mblk_t *cr_pkt, 57 uint_t ip_hdr_len, sctp_init_chunk_t *iack) 58 { 59 60 sctp_hdr_t *sctph; 61 sctp_chunk_hdr_t *ich; 62 sctp_init_chunk_t *init; 63 int err; 64 uint_t sctp_options; 65 conn_t *aconnp; 66 conn_t *lconnp; 67 cred_t *credp; 68 ts_label_t *tslp; 69 sctp_stack_t *sctps = listener->sctp_sctps; 70 71 sctph = (sctp_hdr_t *)(cr_pkt->b_rptr + ip_hdr_len); 72 ASSERT(OK_32PTR(sctph)); 73 74 acceptor->sctp_lport = listener->sctp_lport; 75 acceptor->sctp_fport = sctph->sh_sport; 76 77 ich = (sctp_chunk_hdr_t *)(iack + 1); 78 init = (sctp_init_chunk_t *)(ich + 1); 79 80 /* 81 * If this is an MLP connection, packets are to be 82 * exchanged using the security label of the received 83 * Cookie packet instead of the server application's label. 84 * Create an effective cred for the connection by attaching 85 * the received packet's security label to the server 86 * application's cred. 87 */ 88 aconnp = acceptor->sctp_connp; 89 lconnp = listener->sctp_connp; 90 ASSERT(aconnp->conn_effective_cred == NULL); 91 if (lconnp->conn_mlp_type != mlptSingle && 92 (credp = msg_getcred(cr_pkt, NULL)) != NULL && 93 (tslp = crgetlabel(credp)) != NULL) { 94 if ((aconnp->conn_effective_cred = copycred_from_tslabel( 95 aconnp->conn_cred, tslp, KM_NOSLEEP)) == NULL) 96 return (ENOMEM); 97 } 98 99 /* acceptor isn't in any fanouts yet, so don't need to hold locks */ 100 ASSERT(acceptor->sctp_faddrs == NULL); 101 err = sctp_get_addrparams(acceptor, listener, cr_pkt, ich, 102 &sctp_options); 103 if (err != 0) 104 return (err); 105 106 if ((err = sctp_set_hdraddrs(acceptor)) != 0) 107 return (err); 108 109 if ((sctp_options & SCTP_PRSCTP_OPTION) && 110 listener->sctp_prsctp_aware && sctps->sctps_prsctp_enabled) { 111 acceptor->sctp_prsctp_aware = B_TRUE; 112 } else { 113 acceptor->sctp_prsctp_aware = B_FALSE; 114 } 115 /* The new sctp_t is fully bound now. */ 116 acceptor->sctp_connp->conn_fully_bound = B_TRUE; 117 118 /* Get initial TSNs */ 119 acceptor->sctp_ltsn = ntohl(iack->sic_inittsn); 120 acceptor->sctp_recovery_tsn = acceptor->sctp_lastack_rxd = 121 acceptor->sctp_ltsn - 1; 122 acceptor->sctp_adv_pap = acceptor->sctp_lastack_rxd; 123 /* Serial numbers are initialized to the same value as the TSNs */ 124 acceptor->sctp_lcsn = acceptor->sctp_ltsn; 125 126 if (!sctp_initialize_params(acceptor, init, iack)) 127 return (ENOMEM); 128 129 /* 130 * Copy sctp_secret from the listener in case we need to validate 131 * a possibly delayed cookie. 132 */ 133 bcopy(listener->sctp_secret, acceptor->sctp_secret, SCTP_SECRET_LEN); 134 bcopy(listener->sctp_old_secret, acceptor->sctp_old_secret, 135 SCTP_SECRET_LEN); 136 acceptor->sctp_last_secret_update = lbolt64; 137 138 /* 139 * After acceptor is inserted in the hash list, it can be found. 140 * So we need to lock it here. 141 */ 142 RUN_SCTP(acceptor); 143 144 sctp_conn_hash_insert(&sctps->sctps_conn_fanout[ 145 SCTP_CONN_HASH(sctps, acceptor->sctp_ports)], acceptor, 0); 146 sctp_bind_hash_insert(&sctps->sctps_bind_fanout[ 147 SCTP_BIND_HASH(ntohs(acceptor->sctp_lport))], acceptor, 0); 148 149 /* 150 * No need to check for multicast destination since ip will only pass 151 * up multicasts to those that have expressed interest 152 * TODO: what about rejecting broadcasts? 153 * Also check that source is not a multicast or broadcast address. 154 */ 155 /* XXXSCTP */ 156 acceptor->sctp_state = SCTPS_ESTABLISHED; 157 acceptor->sctp_assoc_start_time = (uint32_t)lbolt; 158 /* 159 * listener->sctp_rwnd should be the default window size or a 160 * window size changed via SO_RCVBUF option. 161 */ 162 acceptor->sctp_rwnd = listener->sctp_rwnd; 163 acceptor->sctp_irwnd = acceptor->sctp_rwnd; 164 acceptor->sctp_pd_point = acceptor->sctp_rwnd; 165 acceptor->sctp_upcalls = listener->sctp_upcalls; 166 167 return (0); 168 } 169 170 /* Process the COOKIE packet, mp, directed at the listener 'sctp' */ 171 sctp_t * 172 sctp_conn_request(sctp_t *sctp, mblk_t *mp, uint_t ifindex, uint_t ip_hdr_len, 173 sctp_init_chunk_t *iack, mblk_t *ipsec_mp) 174 { 175 sctp_t *eager; 176 uint_t ipvers; 177 ip6_t *ip6h; 178 int err; 179 conn_t *connp, *econnp; 180 sctp_stack_t *sctps; 181 struct sock_proto_props sopp; 182 cred_t *cr; 183 pid_t cpid; 184 185 /* 186 * No need to check for duplicate as this is the listener 187 * and we are holding the lock. This means that no new 188 * connection can be created out of it. And since the 189 * fanout already done cannot find a match, it means that 190 * there is no duplicate. 191 */ 192 ipvers = IPH_HDR_VERSION(mp->b_rptr); 193 ASSERT(ipvers == IPV6_VERSION || ipvers == IPV4_VERSION); 194 ASSERT(OK_32PTR(mp->b_rptr)); 195 196 if ((eager = sctp_create_eager(sctp)) == NULL) { 197 return (NULL); 198 } 199 200 if (ipvers != IPV4_VERSION) { 201 ip6h = (ip6_t *)mp->b_rptr; 202 if (IN6_IS_ADDR_LINKLOCAL(&ip6h->ip6_src)) 203 eager->sctp_linklocal = 1; 204 /* 205 * Record ifindex (might be zero) to tie this connection to 206 * that interface if either the listener was bound or 207 * if the connection is using link-local addresses. 208 */ 209 if (sctp->sctp_bound_if == ifindex || 210 IN6_IS_ADDR_LINKLOCAL(&ip6h->ip6_src)) 211 eager->sctp_bound_if = ifindex; 212 /* 213 * XXX broken. bound_if is always overwritten by statement 214 * below. What is the right thing to do here? 215 */ 216 eager->sctp_bound_if = sctp->sctp_bound_if; 217 } 218 219 connp = sctp->sctp_connp; 220 sctps = sctp->sctp_sctps; 221 econnp = eager->sctp_connp; 222 223 if (connp->conn_policy != NULL) { 224 ipsec_in_t *ii; 225 226 ASSERT(ipsec_mp != NULL); 227 ii = (ipsec_in_t *)(ipsec_mp->b_rptr); 228 ASSERT(ii->ipsec_in_policy == NULL); 229 IPPH_REFHOLD(connp->conn_policy); 230 ii->ipsec_in_policy = connp->conn_policy; 231 232 ipsec_mp->b_datap->db_type = IPSEC_POLICY_SET; 233 if (!ip_bind_ipsec_policy_set(econnp, ipsec_mp)) { 234 sctp_close_eager(eager); 235 BUMP_MIB(&sctps->sctps_mib, sctpListenDrop); 236 return (NULL); 237 } 238 } 239 240 if (ipsec_mp != NULL) { 241 /* 242 * XXX need to fix the cached policy issue here. 243 * We temporarily set the conn_src/conn_rem here so 244 * that IPsec can use it for the latched policy 245 * selector. This is obvioursly wrong as SCTP can 246 * use different addresses... 247 */ 248 if (ipvers == IPV4_VERSION) { 249 ipha_t *ipha; 250 251 ipha = (ipha_t *)mp->b_rptr; 252 econnp->conn_src = ipha->ipha_dst; 253 econnp->conn_rem = ipha->ipha_src; 254 } else { 255 econnp->conn_srcv6 = ip6h->ip6_dst; 256 econnp->conn_remv6 = ip6h->ip6_src; 257 } 258 } 259 if (ipsec_conn_cache_policy(econnp, ipvers == IPV4_VERSION) != 0) { 260 sctp_close_eager(eager); 261 BUMP_MIB(&sctps->sctps_mib, sctpListenDrop); 262 return (NULL); 263 } 264 265 /* Save for getpeerucred */ 266 cr = msg_getcred(mp, &cpid); 267 268 err = sctp_accept_comm(sctp, eager, mp, ip_hdr_len, iack); 269 if (err) { 270 sctp_close_eager(eager); 271 BUMP_MIB(&sctps->sctps_mib, sctpListenDrop); 272 return (NULL); 273 } 274 275 /* 276 * On a clustered note send this notification to the clustering 277 * subsystem. 278 */ 279 if (cl_sctp_connect != NULL) { 280 uchar_t *slist; 281 uchar_t *flist; 282 size_t fsize; 283 size_t ssize; 284 285 fsize = sizeof (in6_addr_t) * eager->sctp_nfaddrs; 286 ssize = sizeof (in6_addr_t) * eager->sctp_nsaddrs; 287 slist = kmem_alloc(ssize, KM_NOSLEEP); 288 flist = kmem_alloc(fsize, KM_NOSLEEP); 289 if (slist == NULL || flist == NULL) { 290 if (slist != NULL) 291 kmem_free(slist, ssize); 292 if (flist != NULL) 293 kmem_free(flist, fsize); 294 sctp_close_eager(eager); 295 BUMP_MIB(&sctps->sctps_mib, sctpListenDrop); 296 SCTP_KSTAT(sctps, sctp_cl_connect); 297 return (NULL); 298 } 299 /* The clustering module frees these list */ 300 sctp_get_saddr_list(eager, slist, ssize); 301 sctp_get_faddr_list(eager, flist, fsize); 302 (*cl_sctp_connect)(eager->sctp_family, slist, 303 eager->sctp_nsaddrs, eager->sctp_lport, flist, 304 eager->sctp_nfaddrs, eager->sctp_fport, B_FALSE, 305 (cl_sctp_handle_t)eager); 306 } 307 308 /* Connection established, so send up the conn_ind */ 309 if ((eager->sctp_ulpd = sctp->sctp_ulp_newconn(sctp->sctp_ulpd, 310 (sock_lower_handle_t)eager, NULL, cr, cpid, 311 &eager->sctp_upcalls)) == NULL) { 312 sctp_close_eager(eager); 313 BUMP_MIB(&sctps->sctps_mib, sctpListenDrop); 314 return (NULL); 315 } 316 ASSERT(SCTP_IS_DETACHED(eager)); 317 eager->sctp_detached = B_FALSE; 318 bzero(&sopp, sizeof (sopp)); 319 sopp.sopp_flags = SOCKOPT_MAXBLK|SOCKOPT_WROFF; 320 sopp.sopp_maxblk = strmsgsz; 321 if (eager->sctp_family == AF_INET) { 322 sopp.sopp_wroff = sctps->sctps_wroff_xtra + 323 sizeof (sctp_data_hdr_t) + sctp->sctp_hdr_len; 324 } else { 325 sopp.sopp_wroff = sctps->sctps_wroff_xtra + 326 sizeof (sctp_data_hdr_t) + sctp->sctp_hdr6_len; 327 } 328 eager->sctp_ulp_prop(eager->sctp_ulpd, &sopp); 329 return (eager); 330 } 331 332 /* 333 * Connect to a peer - this function inserts the sctp in the 334 * bind and conn fanouts, sends the INIT, and replies to the client 335 * with an OK ack. 336 */ 337 int 338 sctp_connect(sctp_t *sctp, const struct sockaddr *dst, uint32_t addrlen) 339 { 340 sin_t *sin; 341 sin6_t *sin6; 342 in6_addr_t dstaddr; 343 in_port_t dstport; 344 mblk_t *initmp; 345 sctp_tf_t *tbf; 346 sctp_t *lsctp; 347 char buf[INET6_ADDRSTRLEN]; 348 int sleep = sctp->sctp_cansleep ? KM_SLEEP : KM_NOSLEEP; 349 int hdrlen; 350 ip6_rthdr_t *rth; 351 int err; 352 sctp_faddr_t *cur_fp; 353 sctp_stack_t *sctps = sctp->sctp_sctps; 354 struct sock_proto_props sopp; 355 356 /* 357 * Determine packet type based on type of address passed in 358 * the request should contain an IPv4 or IPv6 address. 359 * Make sure that address family matches the type of 360 * family of the the address passed down 361 */ 362 if (addrlen < sizeof (sin_t)) { 363 return (EINVAL); 364 } 365 switch (dst->sa_family) { 366 case AF_INET: 367 sin = (sin_t *)dst; 368 369 /* Check for attempt to connect to non-unicast */ 370 if (CLASSD(sin->sin_addr.s_addr) || 371 (sin->sin_addr.s_addr == INADDR_BROADCAST)) { 372 ip0dbg(("sctp_connect: non-unicast\n")); 373 return (EINVAL); 374 } 375 if (sctp->sctp_connp->conn_ipv6_v6only) 376 return (EAFNOSUPPORT); 377 378 /* convert to v6 mapped */ 379 /* Check for attempt to connect to INADDR_ANY */ 380 if (sin->sin_addr.s_addr == INADDR_ANY) { 381 struct in_addr v4_addr; 382 /* 383 * SunOS 4.x and 4.3 BSD allow an application 384 * to connect a TCP socket to INADDR_ANY. 385 * When they do this, the kernel picks the 386 * address of one interface and uses it 387 * instead. The kernel usually ends up 388 * picking the address of the loopback 389 * interface. This is an undocumented feature. 390 * However, we provide the same thing here 391 * in case any TCP apps that use this feature 392 * are being ported to SCTP... 393 */ 394 v4_addr.s_addr = htonl(INADDR_LOOPBACK); 395 IN6_INADDR_TO_V4MAPPED(&v4_addr, &dstaddr); 396 } else { 397 IN6_INADDR_TO_V4MAPPED(&sin->sin_addr, &dstaddr); 398 } 399 dstport = sin->sin_port; 400 if (sin->sin_family == AF_INET) { 401 hdrlen = sctp->sctp_hdr_len; 402 } else { 403 hdrlen = sctp->sctp_hdr6_len; 404 } 405 break; 406 case AF_INET6: 407 sin6 = (sin6_t *)dst; 408 /* Check for attempt to connect to non-unicast. */ 409 if ((addrlen < sizeof (sin6_t)) || 410 IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)) { 411 ip0dbg(("sctp_connect: non-unicast\n")); 412 return (EINVAL); 413 } 414 if (sctp->sctp_connp->conn_ipv6_v6only && 415 IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) { 416 return (EAFNOSUPPORT); 417 } 418 /* check for attempt to connect to unspec */ 419 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) { 420 dstaddr = ipv6_loopback; 421 } else { 422 dstaddr = sin6->sin6_addr; 423 if (IN6_IS_ADDR_LINKLOCAL(&dstaddr)) 424 sctp->sctp_linklocal = 1; 425 } 426 dstport = sin6->sin6_port; 427 hdrlen = sctp->sctp_hdr6_len; 428 break; 429 default: 430 dprint(1, ("sctp_connect: unknown family %d\n", 431 dst->sa_family)); 432 return (EAFNOSUPPORT); 433 } 434 435 (void) inet_ntop(AF_INET6, &dstaddr, buf, sizeof (buf)); 436 dprint(1, ("sctp_connect: attempting connect to %s...\n", buf)); 437 438 RUN_SCTP(sctp); 439 440 if (sctp->sctp_family != dst->sa_family || 441 (sctp->sctp_connp->conn_state_flags & CONN_CLOSING)) { 442 WAKE_SCTP(sctp); 443 return (EINVAL); 444 } 445 446 switch (sctp->sctp_state) { 447 case SCTPS_IDLE: { 448 struct sockaddr_storage ss; 449 450 /* 451 * We support a quick connect capability here, allowing 452 * clients to transition directly from IDLE to COOKIE_WAIT. 453 * sctp_bindi will pick an unused port, insert the connection 454 * in the bind hash and transition to BOUND state. SCTP 455 * picks and uses what it considers the optimal local address 456 * set (just like specifiying INADDR_ANY to bind()). 457 */ 458 dprint(1, ("sctp_connect: idle, attempting bind...\n")); 459 ASSERT(sctp->sctp_nsaddrs == 0); 460 461 bzero(&ss, sizeof (ss)); 462 ss.ss_family = sctp->sctp_family; 463 WAKE_SCTP(sctp); 464 if ((err = sctp_bind(sctp, (struct sockaddr *)&ss, 465 sizeof (ss))) != 0) { 466 return (err); 467 } 468 RUN_SCTP(sctp); 469 /* FALLTHRU */ 470 } 471 472 case SCTPS_BOUND: 473 ASSERT(sctp->sctp_nsaddrs > 0); 474 475 /* do the connect */ 476 /* XXX check for attempt to connect to self */ 477 sctp->sctp_fport = dstport; 478 479 ASSERT(sctp->sctp_iphc); 480 ASSERT(sctp->sctp_iphc6); 481 482 /* 483 * Don't allow this connection to completely duplicate 484 * an existing connection. 485 * 486 * Ensure that the duplicate check and insertion is atomic. 487 */ 488 sctp_conn_hash_remove(sctp); 489 tbf = &sctps->sctps_conn_fanout[SCTP_CONN_HASH(sctps, 490 sctp->sctp_ports)]; 491 mutex_enter(&tbf->tf_lock); 492 lsctp = sctp_lookup(sctp, &dstaddr, tbf, &sctp->sctp_ports, 493 SCTPS_COOKIE_WAIT); 494 if (lsctp != NULL) { 495 /* found a duplicate connection */ 496 mutex_exit(&tbf->tf_lock); 497 SCTP_REFRELE(lsctp); 498 WAKE_SCTP(sctp); 499 return (EADDRINUSE); 500 } 501 /* 502 * OK; set up the peer addr (this may grow after we get 503 * the INIT ACK from the peer with additional addresses). 504 */ 505 if ((err = sctp_add_faddr(sctp, &dstaddr, sleep, 506 B_FALSE)) != 0) { 507 mutex_exit(&tbf->tf_lock); 508 WAKE_SCTP(sctp); 509 return (err); 510 } 511 cur_fp = sctp->sctp_faddrs; 512 513 /* No valid src addr, return. */ 514 if (cur_fp->state == SCTP_FADDRS_UNREACH) { 515 mutex_exit(&tbf->tf_lock); 516 WAKE_SCTP(sctp); 517 return (EADDRNOTAVAIL); 518 } 519 520 sctp->sctp_primary = cur_fp; 521 sctp->sctp_current = cur_fp; 522 sctp->sctp_mss = cur_fp->sfa_pmss; 523 sctp_conn_hash_insert(tbf, sctp, 1); 524 mutex_exit(&tbf->tf_lock); 525 526 /* initialize composite headers */ 527 if ((err = sctp_set_hdraddrs(sctp)) != 0) { 528 sctp_conn_hash_remove(sctp); 529 WAKE_SCTP(sctp); 530 return (err); 531 } 532 533 /* 534 * Massage a routing header (if present) putting the first hop 535 * in ip6_dst. 536 */ 537 rth = ip_find_rthdr_v6(sctp->sctp_ip6h, 538 (uint8_t *)sctp->sctp_sctph6); 539 if (rth != NULL) { 540 (void) ip_massage_options_v6(sctp->sctp_ip6h, rth, 541 sctps->sctps_netstack); 542 } 543 544 /* 545 * Turn off the don't fragment bit on the (only) faddr, 546 * so that if one of the messages exchanged during the 547 * initialization sequence exceeds the path mtu, it 548 * at least has a chance to get there. SCTP does no 549 * fragmentation of initialization messages. The DF bit 550 * will be turned on again in sctp_send_cookie_echo() 551 * (but the cookie echo will still be sent with the df bit 552 * off). 553 */ 554 cur_fp->df = B_FALSE; 555 556 /* Mark this address as alive */ 557 cur_fp->state = SCTP_FADDRS_ALIVE; 558 559 /* This sctp_t is fully bound now. */ 560 sctp->sctp_connp->conn_fully_bound = B_TRUE; 561 562 /* Send the INIT to the peer */ 563 SCTP_FADDR_TIMER_RESTART(sctp, cur_fp, cur_fp->rto); 564 sctp->sctp_state = SCTPS_COOKIE_WAIT; 565 /* 566 * sctp_init_mp() could result in modifying the source 567 * address list, so take the hash lock. 568 */ 569 mutex_enter(&tbf->tf_lock); 570 initmp = sctp_init_mp(sctp); 571 if (initmp == NULL) { 572 mutex_exit(&tbf->tf_lock); 573 /* 574 * It may happen that all the source addresses 575 * (loopback/link local) are removed. In that case, 576 * faile the connect. 577 */ 578 if (sctp->sctp_nsaddrs == 0) { 579 sctp_conn_hash_remove(sctp); 580 SCTP_FADDR_TIMER_STOP(cur_fp); 581 WAKE_SCTP(sctp); 582 return (EADDRNOTAVAIL); 583 } 584 585 /* Otherwise, let the retransmission timer retry */ 586 WAKE_SCTP(sctp); 587 goto notify_ulp; 588 } 589 mutex_exit(&tbf->tf_lock); 590 591 /* 592 * On a clustered note send this notification to the clustering 593 * subsystem. 594 */ 595 if (cl_sctp_connect != NULL) { 596 uchar_t *slist; 597 uchar_t *flist; 598 size_t ssize; 599 size_t fsize; 600 601 fsize = sizeof (in6_addr_t) * sctp->sctp_nfaddrs; 602 ssize = sizeof (in6_addr_t) * sctp->sctp_nsaddrs; 603 slist = kmem_alloc(ssize, KM_SLEEP); 604 flist = kmem_alloc(fsize, KM_SLEEP); 605 /* The clustering module frees the lists */ 606 sctp_get_saddr_list(sctp, slist, ssize); 607 sctp_get_faddr_list(sctp, flist, fsize); 608 (*cl_sctp_connect)(sctp->sctp_family, slist, 609 sctp->sctp_nsaddrs, sctp->sctp_lport, 610 flist, sctp->sctp_nfaddrs, sctp->sctp_fport, 611 B_TRUE, (cl_sctp_handle_t)sctp); 612 } 613 WAKE_SCTP(sctp); 614 /* OK to call IP_PUT() here instead of sctp_add_sendq(). */ 615 CONN_INC_REF(sctp->sctp_connp); 616 initmp->b_flag |= MSGHASREF; 617 IP_PUT(initmp, sctp->sctp_connp, sctp->sctp_current->isv4); 618 BUMP_LOCAL(sctp->sctp_opkts); 619 620 notify_ulp: 621 bzero(&sopp, sizeof (sopp)); 622 sopp.sopp_flags = SOCKOPT_WROFF; 623 sopp.sopp_wroff = sctps->sctps_wroff_xtra + hdrlen + 624 sizeof (sctp_data_hdr_t); 625 sctp->sctp_ulp_prop(sctp->sctp_ulpd, &sopp); 626 627 return (0); 628 default: 629 ip0dbg(("sctp_connect: invalid state. %d\n", sctp->sctp_state)); 630 WAKE_SCTP(sctp); 631 return (EINVAL); 632 } 633 } 634