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 2010 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/socket.h> 32 #include <sys/kmem.h> 33 #include <sys/strsubr.h> 34 #include <sys/strsun.h> 35 36 #include <netinet/in.h> 37 #include <netinet/ip6.h> 38 #include <netinet/sctp.h> 39 40 #include <inet/common.h> 41 #include <inet/ip.h> 42 #include <inet/ip6.h> 43 #include <inet/mib2.h> 44 #include <inet/ipclassifier.h> 45 #include "sctp_impl.h" 46 #include "sctp_asconf.h" 47 #include "sctp_addr.h" 48 49 typedef struct sctp_asconf_s { 50 mblk_t *head; 51 uint32_t cid; 52 } sctp_asconf_t; 53 54 /* 55 * This is only used on a clustered node to maintain pre-allocated buffer info. 56 * before sending an ASCONF chunk. The reason for pre-allocation is we don't 57 * want to fail allocating memory when we get then ASCONF-ACK in order to 58 * update the clustering subsystem's state for this assoc. 59 */ 60 typedef struct sctp_cl_ainfo_s { 61 uchar_t *sctp_cl_alist; 62 size_t sctp_cl_asize; 63 uchar_t *sctp_cl_dlist; 64 size_t sctp_cl_dsize; 65 } sctp_cl_ainfo_t; 66 67 /* 68 * The ASCONF chunk per-parameter request interface. ph is the 69 * parameter header for the parameter in the request, and cid 70 * is the parameters correlation ID. cont should be set to 1 71 * if the ASCONF framework should continue processing request 72 * parameters following this one, or 0 if it should stop. If 73 * cont is -1, this indicates complete memory depletion, which 74 * will cause the ASCONF framework to abort building a reply. If 75 * act is 1, the callback should take whatever action it needs 76 * to fulfil this request. If act is 0, this request has already 77 * been processed, so the callback should only verify and pass 78 * back error parameters, and not take any action. 79 * 80 * The callback should return an mblk with any reply enclosed, 81 * with the correlation ID in the first four bytes of the 82 * message. A NULL return implies implicit success to the 83 * requestor. 84 */ 85 typedef mblk_t *sctp_asconf_func_t(sctp_t *, sctp_parm_hdr_t *ph, uint32_t cid, 86 sctp_faddr_t *, int *cont, int act, in6_addr_t *addr); 87 88 /* 89 * The ASCONF chunk per-parameter ACK interface. ph is the parameter 90 * header for the parameter returned in the ACK, and oph is the 91 * original parameter sent out in the ASCONF request. 92 * If the peer implicitly responded OK (by not including an 93 * explicit OK for the request), ph will be NULL. 94 * ph can also point to an Unrecognized Parameter parameter, 95 * in which case the peer did not understand the request 96 * parameter. 97 * 98 * ph and oph parameter headers are in host byte order. Encapsulated 99 * parameters will still be in network byte order. 100 */ 101 typedef void sctp_asconf_ack_func_t(sctp_t *, sctp_parm_hdr_t *ph, 102 sctp_parm_hdr_t *oph, sctp_faddr_t *, in6_addr_t *addr); 103 104 typedef struct { 105 uint16_t id; 106 sctp_asconf_func_t *asconf; 107 sctp_asconf_ack_func_t *asconf_ack; 108 } dispatch_t; 109 110 static sctp_asconf_func_t sctp_addip_req, sctp_setprim_req, 111 sctp_asconf_unrec_parm; 112 113 static sctp_asconf_ack_func_t sctp_addip_ack, sctp_setprim_ack, 114 sctp_asconf_ack_unrec_parm; 115 116 static const dispatch_t sctp_asconf_dispatch_tbl[] = { 117 /* ID ASCONF ASCONF_ACK */ 118 { PARM_ADD_IP, sctp_addip_req, sctp_addip_ack }, 119 { PARM_DEL_IP, sctp_addip_req, sctp_addip_ack }, 120 { PARM_SET_PRIMARY, sctp_setprim_req, sctp_setprim_ack } 121 }; 122 123 static const dispatch_t sctp_asconf_default_dispatch = { 124 0, sctp_asconf_unrec_parm, sctp_asconf_ack_unrec_parm 125 }; 126 127 /* 128 * ASCONF framework 129 */ 130 131 static const dispatch_t * 132 sctp_lookup_asconf_dispatch(int id) 133 { 134 int i; 135 136 for (i = 0; i < A_CNT(sctp_asconf_dispatch_tbl); i++) { 137 if (sctp_asconf_dispatch_tbl[i].id == id) { 138 return (sctp_asconf_dispatch_tbl + i); 139 } 140 } 141 142 return (&sctp_asconf_default_dispatch); 143 } 144 145 /* 146 * Frees mp on failure 147 */ 148 static mblk_t * 149 sctp_asconf_prepend_errwrap(mblk_t *mp, uint32_t cid) 150 { 151 mblk_t *wmp; 152 sctp_parm_hdr_t *wph; 153 154 /* Prepend a wrapper err cause ind param */ 155 wmp = allocb(sizeof (*wph) + sizeof (cid), BPRI_MED); 156 if (wmp == NULL) { 157 freemsg(mp); 158 return (NULL); 159 } 160 wmp->b_wptr += sizeof (*wph) + sizeof (cid); 161 wph = (sctp_parm_hdr_t *)wmp->b_rptr; 162 wph->sph_type = htons(PARM_ERROR_IND); 163 wph->sph_len = htons(msgdsize(mp) + sizeof (*wph) + sizeof (cid)); 164 bcopy(&cid, wph + 1, sizeof (uint32_t)); 165 166 wmp->b_cont = mp; 167 return (wmp); 168 } 169 170 /*ARGSUSED*/ 171 static mblk_t * 172 sctp_asconf_unrec_parm(sctp_t *sctp, sctp_parm_hdr_t *ph, uint32_t cid, 173 sctp_faddr_t *fp, int *cont, int act, in6_addr_t *addr) 174 { 175 mblk_t *mp = NULL; 176 177 /* Unrecognized param; check the high order bits */ 178 if ((ph->sph_type & SCTP_UNREC_PARAM_MASK) == 179 (SCTP_CONT_PROC_PARAMS | SCTP_REPORT_THIS_PARAM)) { 180 /* report unrecognized param, and keep processing */ 181 sctp_add_unrec_parm(ph, &mp, B_FALSE); 182 if (mp == NULL) { 183 *cont = -1; 184 return (NULL); 185 } 186 /* Prepend a the CID and a wrapper err cause ind param */ 187 mp = sctp_asconf_prepend_errwrap(mp, cid); 188 if (mp == NULL) { 189 *cont = -1; 190 return (NULL); 191 } 192 193 *cont = 1; 194 return (mp); 195 } 196 if (ph->sph_type & SCTP_REPORT_THIS_PARAM) { 197 /* Stop processing and drop; report unrecognized param */ 198 sctp_add_unrec_parm(ph, &mp, B_FALSE); 199 if (mp == NULL) { 200 *cont = -1; 201 return (NULL); 202 } 203 /* Prepend a the CID and a wrapper err cause ind param */ 204 mp = sctp_asconf_prepend_errwrap(mp, cid); 205 if (mp == NULL) { 206 *cont = -1; 207 return (NULL); 208 } 209 210 *cont = 0; 211 return (mp); 212 } 213 if (ph->sph_type & SCTP_CONT_PROC_PARAMS) { 214 /* skip and continue processing */ 215 *cont = 1; 216 return (NULL); 217 } 218 219 /* 2 high bits are clear; stop processing and drop packet */ 220 *cont = 0; 221 return (NULL); 222 } 223 224 /*ARGSUSED*/ 225 static void 226 sctp_asconf_ack_unrec_parm(sctp_t *sctp, sctp_parm_hdr_t *ph, 227 sctp_parm_hdr_t *oph, sctp_faddr_t *fp, in6_addr_t *laddr) 228 { 229 ASSERT(ph); 230 sctp_error_event(sctp, (sctp_chunk_hdr_t *)ph, B_TRUE); 231 } 232 233 static void 234 sctp_asconf_init(sctp_asconf_t *asc) 235 { 236 ASSERT(asc != NULL); 237 238 asc->head = NULL; 239 asc->cid = 0; 240 } 241 242 static int 243 sctp_asconf_add(sctp_asconf_t *asc, mblk_t *mp) 244 { 245 uint32_t *cp; 246 247 /* XXX can't exceed MTU */ 248 249 cp = (uint32_t *)(mp->b_rptr + sizeof (sctp_parm_hdr_t)); 250 *cp = asc->cid++; 251 252 if (asc->head == NULL) 253 asc->head = mp; 254 else 255 linkb(asc->head, mp); 256 257 return (0); 258 } 259 260 static void 261 sctp_asconf_destroy(sctp_asconf_t *asc) 262 { 263 if (asc->head != NULL) { 264 freemsg(asc->head); 265 asc->head = NULL; 266 } 267 asc->cid = 0; 268 } 269 270 static int 271 sctp_asconf_send(sctp_t *sctp, sctp_asconf_t *asc, sctp_faddr_t *fp, 272 sctp_cl_ainfo_t *ainfo) 273 { 274 mblk_t *mp, *nmp; 275 sctp_chunk_hdr_t *ch; 276 boolean_t isv4; 277 size_t msgsize; 278 279 ASSERT(asc != NULL && asc->head != NULL); 280 281 isv4 = (fp != NULL) ? fp->isv4 : sctp->sctp_current->isv4; 282 283 /* SCTP chunk header + Serial Number + Address Param TLV */ 284 msgsize = sizeof (*ch) + sizeof (uint32_t) + 285 (isv4 ? PARM_ADDR4_LEN : PARM_ADDR6_LEN); 286 287 mp = allocb(msgsize, BPRI_MED); 288 if (mp == NULL) 289 return (ENOMEM); 290 291 mp->b_wptr += msgsize; 292 mp->b_cont = asc->head; 293 294 ch = (sctp_chunk_hdr_t *)mp->b_rptr; 295 ch->sch_id = CHUNK_ASCONF; 296 ch->sch_flags = 0; 297 ch->sch_len = htons(msgdsize(mp)); 298 299 nmp = msgpullup(mp, -1); 300 if (nmp == NULL) { 301 freeb(mp); 302 return (ENOMEM); 303 } 304 305 /* 306 * Stash the address list and the count so that when the operation 307 * completes, i.e. when as get an ACK, we can update the clustering's 308 * state for this association. 309 */ 310 if (ainfo != NULL) { 311 ASSERT(cl_sctp_assoc_change != NULL); 312 ASSERT(nmp->b_prev == NULL); 313 nmp->b_prev = (mblk_t *)ainfo; 314 } 315 /* Clean up the temporary mblk chain */ 316 freemsg(mp); 317 asc->head = NULL; 318 asc->cid = 0; 319 320 /* Queue it ... */ 321 if (sctp->sctp_cxmit_list == NULL) { 322 sctp->sctp_cxmit_list = nmp; 323 } else { 324 linkb(sctp->sctp_cxmit_list, nmp); 325 } 326 327 BUMP_LOCAL(sctp->sctp_obchunks); 328 329 /* And try to send it. */ 330 sctp_wput_asconf(sctp, fp); 331 332 return (0); 333 } 334 335 /* 336 * If the peer does not understand an ASCONF chunk, we simply 337 * clear out the cxmit_list, since we can send nothing further 338 * that the peer will understand. 339 * 340 * Assumes chunk length has already been checked. 341 */ 342 /*ARGSUSED*/ 343 void 344 sctp_asconf_free_cxmit(sctp_t *sctp, sctp_chunk_hdr_t *ch) 345 { 346 mblk_t *mp; 347 mblk_t *mp1; 348 sctp_cl_ainfo_t *ainfo; 349 350 if (sctp->sctp_cxmit_list == NULL) { 351 /* Nothing pending */ 352 return; 353 } 354 355 mp = sctp->sctp_cxmit_list; 356 while (mp != NULL) { 357 mp1 = mp->b_cont; 358 mp->b_cont = NULL; 359 if (mp->b_prev != NULL) { 360 ainfo = (sctp_cl_ainfo_t *)mp->b_prev; 361 mp->b_prev = NULL; 362 kmem_free(ainfo->sctp_cl_alist, ainfo->sctp_cl_asize); 363 kmem_free(ainfo->sctp_cl_dlist, ainfo->sctp_cl_dsize); 364 kmem_free(ainfo, sizeof (*ainfo)); 365 } 366 freeb(mp); 367 mp = mp1; 368 } 369 sctp->sctp_cxmit_list = NULL; 370 } 371 372 void 373 sctp_input_asconf(sctp_t *sctp, sctp_chunk_hdr_t *ch, sctp_faddr_t *fp) 374 { 375 const dispatch_t *dp; 376 mblk_t *hmp; 377 mblk_t *mp; 378 uint32_t *idp; 379 uint32_t *hidp; 380 ssize_t rlen; 381 sctp_parm_hdr_t *ph; 382 sctp_chunk_hdr_t *ach; 383 int cont; 384 int act; 385 uint16_t plen; 386 uchar_t *alist = NULL; 387 size_t asize = 0; 388 uchar_t *dlist = NULL; 389 size_t dsize = 0; 390 uchar_t *aptr = NULL; 391 uchar_t *dptr = NULL; 392 int acount = 0; 393 int dcount = 0; 394 sctp_stack_t *sctps = sctp->sctp_sctps; 395 396 ASSERT(ch->sch_id == CHUNK_ASCONF); 397 398 idp = (uint32_t *)(ch + 1); 399 rlen = ntohs(ch->sch_len) - sizeof (*ch) - sizeof (*idp); 400 401 if (rlen < 0 || rlen < sizeof (*idp)) { 402 /* nothing there; bail out */ 403 return; 404 } 405 406 /* Check for duplicates */ 407 *idp = ntohl(*idp); 408 if (*idp == (sctp->sctp_fcsn + 1)) { 409 act = 1; 410 } else if (*idp == sctp->sctp_fcsn) { 411 act = 0; 412 } else { 413 /* stale or malicious packet; drop */ 414 return; 415 } 416 417 /* Create the ASCONF_ACK header */ 418 hmp = sctp_make_mp(sctp, fp, sizeof (*ach) + sizeof (*idp)); 419 if (hmp == NULL) { 420 /* Let the peer retransmit */ 421 SCTP_KSTAT(sctps, sctp_send_asconf_ack_failed); 422 return; 423 } 424 ach = (sctp_chunk_hdr_t *)hmp->b_wptr; 425 ach->sch_id = CHUNK_ASCONF_ACK; 426 ach->sch_flags = 0; 427 /* Set the length later */ 428 hidp = (uint32_t *)(ach + 1); 429 *hidp = htonl(*idp); 430 hmp->b_wptr = (uchar_t *)(hidp + 1); 431 432 /* Move to the Address Parameter */ 433 ph = (sctp_parm_hdr_t *)(idp + 1); 434 if (rlen <= ntohs(ph->sph_len)) { 435 freeb(hmp); 436 return; 437 } 438 439 /* 440 * We already have the association here, so this address parameter 441 * doesn't seem to be very useful, should we make sure this is part 442 * of the association and send an error, if not? 443 * Ignore it for now. 444 */ 445 rlen -= ntohs(ph->sph_len); 446 ph = (sctp_parm_hdr_t *)((char *)ph + ntohs(ph->sph_len)); 447 448 /* 449 * We need to pre-allocate buffer before processing the ASCONF 450 * chunk. We don't want to fail allocating buffers after processing 451 * the ASCONF chunk. So, we walk the list and get the number of 452 * addresses added and/or deleted. 453 */ 454 if (cl_sctp_assoc_change != NULL) { 455 sctp_parm_hdr_t *oph = ph; 456 ssize_t orlen = rlen; 457 458 /* 459 * This not very efficient, but there is no better way of 460 * doing it. It should be fine since normally the param list 461 * will not be very long. 462 */ 463 while (orlen > 0) { 464 /* Sanity checks */ 465 if (orlen < sizeof (*oph)) 466 break; 467 plen = ntohs(oph->sph_len); 468 if (plen < sizeof (*oph) || plen > orlen) 469 break; 470 if (oph->sph_type == htons(PARM_ADD_IP)) 471 acount++; 472 if (oph->sph_type == htons(PARM_DEL_IP)) 473 dcount++; 474 oph = sctp_next_parm(oph, &orlen); 475 if (oph == NULL) 476 break; 477 } 478 if (acount > 0 || dcount > 0) { 479 if (acount > 0) { 480 asize = sizeof (in6_addr_t) * acount; 481 alist = kmem_alloc(asize, KM_NOSLEEP); 482 if (alist == NULL) { 483 freeb(hmp); 484 SCTP_KSTAT(sctps, sctp_cl_assoc_change); 485 return; 486 } 487 } 488 if (dcount > 0) { 489 dsize = sizeof (in6_addr_t) * dcount; 490 dlist = kmem_alloc(dsize, KM_NOSLEEP); 491 if (dlist == NULL) { 492 if (acount > 0) 493 kmem_free(alist, asize); 494 freeb(hmp); 495 SCTP_KSTAT(sctps, sctp_cl_assoc_change); 496 return; 497 } 498 } 499 aptr = alist; 500 dptr = dlist; 501 /* 502 * We will get the actual count when we process 503 * the chunk. 504 */ 505 acount = 0; 506 dcount = 0; 507 } 508 } 509 cont = 1; 510 while (rlen > 0 && cont) { 511 in6_addr_t addr; 512 513 /* Sanity checks */ 514 if (rlen < sizeof (*ph)) 515 break; 516 plen = ntohs(ph->sph_len); 517 if (plen < sizeof (*ph) || plen > rlen) { 518 break; 519 } 520 idp = (uint32_t *)(ph + 1); 521 dp = sctp_lookup_asconf_dispatch(ntohs(ph->sph_type)); 522 ASSERT(dp); 523 if (dp->asconf) { 524 mp = dp->asconf(sctp, ph, *idp, fp, &cont, act, &addr); 525 if (cont == -1) { 526 /* 527 * Not even enough memory to create 528 * an out-of-resources error. Free 529 * everything and return; the peer 530 * should retransmit. 531 */ 532 freemsg(hmp); 533 if (alist != NULL) 534 kmem_free(alist, asize); 535 if (dlist != NULL) 536 kmem_free(dlist, dsize); 537 return; 538 } 539 if (mp != NULL) { 540 linkb(hmp, mp); 541 } else if (act != 0) { 542 /* update the add/delete list */ 543 if (cl_sctp_assoc_change != NULL) { 544 if (ph->sph_type == 545 htons(PARM_ADD_IP)) { 546 ASSERT(alist != NULL); 547 bcopy(&addr, aptr, 548 sizeof (addr)); 549 aptr += sizeof (addr); 550 acount++; 551 } else if (ph->sph_type == 552 htons(PARM_DEL_IP)) { 553 ASSERT(dlist != NULL); 554 bcopy(&addr, dptr, 555 sizeof (addr)); 556 dptr += sizeof (addr); 557 dcount++; 558 } 559 } 560 } 561 } 562 ph = sctp_next_parm(ph, &rlen); 563 if (ph == NULL) 564 break; 565 } 566 567 /* 568 * Update clustering's state for this assoc. Note acount/dcount 569 * could be zero (i.e. if the add/delete address(es) were not 570 * processed successfully). Regardless, if the ?size is > 0, 571 * it is the clustering module's responsibility to free the lists. 572 */ 573 if (cl_sctp_assoc_change != NULL) { 574 (*cl_sctp_assoc_change)(sctp->sctp_connp->conn_family, 575 alist, asize, 576 acount, dlist, dsize, dcount, SCTP_CL_PADDR, 577 (cl_sctp_handle_t)sctp); 578 /* alist and dlist will be freed by the clustering module */ 579 } 580 /* Now that the params have been processed, increment the fcsn */ 581 if (act) { 582 sctp->sctp_fcsn++; 583 } 584 BUMP_LOCAL(sctp->sctp_obchunks); 585 586 if (fp->isv4) 587 ach->sch_len = htons(msgdsize(hmp) - sctp->sctp_hdr_len); 588 else 589 ach->sch_len = htons(msgdsize(hmp) - sctp->sctp_hdr6_len); 590 591 sctp_set_iplen(sctp, hmp, fp->ixa); 592 (void) conn_ip_output(hmp, fp->ixa); 593 BUMP_LOCAL(sctp->sctp_opkts); 594 sctp_validate_peer(sctp); 595 } 596 597 static sctp_parm_hdr_t * 598 sctp_lookup_asconf_param(sctp_parm_hdr_t *ph, uint32_t cid, ssize_t rlen) 599 { 600 uint32_t *idp; 601 602 while (rlen > 0) { 603 idp = (uint32_t *)(ph + 1); 604 if (*idp == cid) { 605 return (ph); 606 } 607 ph = sctp_next_parm(ph, &rlen); 608 if (ph == NULL) 609 break; 610 } 611 return (NULL); 612 } 613 614 void 615 sctp_input_asconf_ack(sctp_t *sctp, sctp_chunk_hdr_t *ch, sctp_faddr_t *fp) 616 { 617 const dispatch_t *dp; 618 uint32_t *idp; 619 uint32_t *snp; 620 ssize_t rlen; 621 ssize_t plen; 622 sctp_parm_hdr_t *ph; 623 sctp_parm_hdr_t *oph; 624 sctp_parm_hdr_t *fph; 625 mblk_t *mp; 626 sctp_chunk_hdr_t *och; 627 int redosrcs = 0; 628 uint16_t param_len; 629 uchar_t *alist; 630 uchar_t *dlist; 631 uint_t acount = 0; 632 uint_t dcount = 0; 633 uchar_t *aptr; 634 uchar_t *dptr; 635 sctp_cl_ainfo_t *ainfo; 636 in6_addr_t addr; 637 638 ASSERT(ch->sch_id == CHUNK_ASCONF_ACK); 639 640 snp = (uint32_t *)(ch + 1); 641 rlen = ntohs(ch->sch_len) - sizeof (*ch) - sizeof (*snp); 642 if (rlen < 0) { 643 return; 644 } 645 646 /* Accept only an ACK for the current serial number */ 647 *snp = ntohl(*snp); 648 if (sctp->sctp_cxmit_list == NULL || *snp != (sctp->sctp_lcsn - 1)) { 649 /* Need to send an abort */ 650 return; 651 } 652 sctp->sctp_cchunk_pend = 0; 653 SCTP_FADDR_RC_TIMER_STOP(fp); 654 655 mp = sctp->sctp_cxmit_list; 656 /* 657 * We fill in the addresses here to update the clustering's state for 658 * this assoc. 659 */ 660 if (mp != NULL && cl_sctp_assoc_change != NULL) { 661 ASSERT(mp->b_prev != NULL); 662 ainfo = (sctp_cl_ainfo_t *)mp->b_prev; 663 alist = ainfo->sctp_cl_alist; 664 dlist = ainfo->sctp_cl_dlist; 665 aptr = alist; 666 dptr = dlist; 667 } 668 669 /* 670 * Pass explicit replies to callbacks: 671 * For each reply in the ACK, look up the corresponding 672 * original parameter in the request using the correlation 673 * ID, and pass it to the right callback. 674 */ 675 och = (sctp_chunk_hdr_t *)sctp->sctp_cxmit_list->b_rptr; 676 677 plen = ntohs(och->sch_len) - sizeof (*och) - sizeof (*idp); 678 idp = (uint32_t *)(och + 1); 679 680 /* Get to the 1st ASCONF param, need to skip Address TLV parm */ 681 fph = (sctp_parm_hdr_t *)(idp + 1); 682 plen -= ntohs(fph->sph_len); 683 fph = (sctp_parm_hdr_t *)((char *)fph + ntohs(fph->sph_len)); 684 ph = (sctp_parm_hdr_t *)(snp + 1); 685 while (rlen > 0) { 686 /* Sanity checks */ 687 if (rlen < sizeof (*ph)) { 688 break; 689 } 690 param_len = ntohs(ph->sph_len); 691 if (param_len < sizeof (*ph) || param_len > rlen) { 692 break; 693 } 694 idp = (uint32_t *)(ph + 1); 695 oph = sctp_lookup_asconf_param(fph, *idp, plen); 696 if (oph != NULL) { 697 dp = sctp_lookup_asconf_dispatch(ntohs(oph->sph_type)); 698 ASSERT(dp); 699 if (dp->asconf_ack) { 700 dp->asconf_ack(sctp, ph, oph, fp, &addr); 701 702 /* hack. see below */ 703 if (oph->sph_type == htons(PARM_ADD_IP) || 704 oph->sph_type == htons(PARM_DEL_IP)) { 705 redosrcs = 1; 706 /* 707 * If the address was sucessfully 708 * processed, add it to the add/delete 709 * list to send to the clustering 710 * module. 711 */ 712 if (cl_sctp_assoc_change != NULL && 713 !SCTP_IS_ADDR_UNSPEC( 714 IN6_IS_ADDR_V4MAPPED(&addr), 715 addr)) { 716 if (oph->sph_type == 717 htons(PARM_ADD_IP)) { 718 bcopy(&addr, aptr, 719 sizeof (addr)); 720 aptr += sizeof (addr); 721 acount++; 722 } else { 723 bcopy(&addr, dptr, 724 sizeof (addr)); 725 dptr += sizeof (addr); 726 dcount++; 727 } 728 } 729 } 730 } 731 } 732 733 ph = sctp_next_parm(ph, &rlen); 734 if (ph == NULL) 735 break; 736 } 737 738 /* 739 * Pass implicit replies to callbacks: 740 * For each original request, look up its parameter 741 * in the ACK. If there is no corresponding reply, 742 * call the callback with a NULL parameter, indicating 743 * success. 744 */ 745 rlen = plen; 746 plen = ntohs(ch->sch_len) - sizeof (*ch) - sizeof (*idp); 747 oph = fph; 748 fph = (sctp_parm_hdr_t *)((char *)ch + sizeof (sctp_chunk_hdr_t) + 749 sizeof (uint32_t)); 750 while (rlen > 0) { 751 idp = (uint32_t *)(oph + 1); 752 ph = sctp_lookup_asconf_param(fph, *idp, plen); 753 if (ph == NULL) { 754 dp = sctp_lookup_asconf_dispatch(ntohs(oph->sph_type)); 755 ASSERT(dp); 756 if (dp->asconf_ack) { 757 dp->asconf_ack(sctp, NULL, oph, fp, &addr); 758 759 /* hack. see below */ 760 if (oph->sph_type == htons(PARM_ADD_IP) || 761 oph->sph_type == htons(PARM_DEL_IP)) { 762 redosrcs = 1; 763 /* 764 * If the address was sucessfully 765 * processed, add it to the add/delete 766 * list to send to the clustering 767 * module. 768 */ 769 if (cl_sctp_assoc_change != NULL && 770 !SCTP_IS_ADDR_UNSPEC( 771 IN6_IS_ADDR_V4MAPPED(&addr), 772 addr)) { 773 if (oph->sph_type == 774 htons(PARM_ADD_IP)) { 775 bcopy(&addr, aptr, 776 sizeof (addr)); 777 aptr += sizeof (addr); 778 acount++; 779 } else { 780 bcopy(&addr, dptr, 781 sizeof (addr)); 782 dptr += sizeof (addr); 783 dcount++; 784 } 785 } 786 } 787 } 788 } 789 oph = sctp_next_parm(oph, &rlen); 790 if (oph == NULL) { 791 break; 792 } 793 } 794 795 /* We can now free up the first chunk in the cxmit list */ 796 sctp->sctp_cxmit_list = mp->b_cont; 797 mp->b_cont = NULL; 798 799 fp = SCTP_CHUNK_DEST(mp); 800 ASSERT(fp != NULL && fp->suna >= MBLKL(mp)); 801 fp->suna -= MBLKL(mp); 802 803 /* 804 * Update clustering's state for this assoc. Note acount/dcount 805 * could be zero (i.e. if the add/delete address(es) did not 806 * succeed). Regardless, if the ?size is > 0, it is the clustering 807 * module's responsibility to free the lists. 808 */ 809 if (cl_sctp_assoc_change != NULL) { 810 ASSERT(mp->b_prev != NULL); 811 mp->b_prev = NULL; 812 ainfo->sctp_cl_alist = NULL; 813 ainfo->sctp_cl_dlist = NULL; 814 (*cl_sctp_assoc_change)(sctp->sctp_connp->conn_family, alist, 815 ainfo->sctp_cl_asize, acount, dlist, ainfo->sctp_cl_dsize, 816 dcount, SCTP_CL_LADDR, (cl_sctp_handle_t)sctp); 817 /* alist and dlist will be freed by the clustering module */ 818 ainfo->sctp_cl_asize = 0; 819 ainfo->sctp_cl_dsize = 0; 820 kmem_free(ainfo, sizeof (*ainfo)); 821 } 822 freeb(mp); 823 824 /* can now send the next control chunk */ 825 if (sctp->sctp_cxmit_list != NULL) 826 sctp_wput_asconf(sctp, NULL); 827 828 /* 829 * If an add-ip or del-ip has completed (successfully or 830 * unsuccessfully), the pool of available source addresses 831 * may have changed, so we need to redo faddr source 832 * address selections. This is a bit of a hack since 833 * this really belongs in the add/del-ip code. However, 834 * that code consists of callbacks called for *each* 835 * add/del-ip parameter, and sctp_redo_faddr_srcs() is 836 * expensive enough that we really don't want to be 837 * doing it for each one. So we do it once here. 838 */ 839 if (redosrcs) 840 sctp_redo_faddr_srcs(sctp); 841 } 842 843 static void 844 sctp_rc_timer(sctp_t *sctp, sctp_faddr_t *fp) 845 { 846 #define SCTP_CLR_SENT_FLAG(mp) ((mp)->b_flag &= ~SCTP_CHUNK_FLAG_SENT) 847 sctp_faddr_t *nfp; 848 sctp_faddr_t *ofp; 849 sctp_stack_t *sctps = sctp->sctp_sctps; 850 851 ASSERT(fp != NULL); 852 853 fp->rc_timer_running = 0; 854 855 if (sctp->sctp_state != SCTPS_ESTABLISHED || 856 sctp->sctp_cxmit_list == NULL) { 857 return; 858 } 859 /* 860 * Not a retransmission, this was deferred due to some error 861 * condition 862 */ 863 if (!SCTP_CHUNK_ISSENT(sctp->sctp_cxmit_list)) { 864 sctp_wput_asconf(sctp, fp); 865 return; 866 } 867 /* 868 * The sent flag indicates if the msg has been sent on this fp. 869 */ 870 SCTP_CLR_SENT_FLAG(sctp->sctp_cxmit_list); 871 /* Retransmission */ 872 if (sctp->sctp_strikes >= sctp->sctp_pa_max_rxt) { 873 /* time to give up */ 874 BUMP_MIB(&sctps->sctps_mib, sctpAborted); 875 sctp_assoc_event(sctp, SCTP_COMM_LOST, 0, NULL); 876 sctp_clean_death(sctp, ETIMEDOUT); 877 return; 878 } 879 if (fp->strikes >= fp->max_retr) { 880 if (sctp_faddr_dead(sctp, fp, SCTP_FADDRS_DOWN) == -1) 881 return; 882 } 883 884 fp->strikes++; 885 sctp->sctp_strikes++; 886 SCTP_CALC_RXT(sctp, fp); 887 888 nfp = sctp_rotate_faddr(sctp, fp); 889 sctp->sctp_cchunk_pend = 0; 890 ofp = SCTP_CHUNK_DEST(sctp->sctp_cxmit_list); 891 SCTP_SET_CHUNK_DEST(sctp->sctp_cxmit_list, NULL); 892 ASSERT(ofp != NULL && ofp == fp); 893 ASSERT(ofp->suna >= MBLKL(sctp->sctp_cxmit_list)); 894 /* 895 * Enter slow start for this destination. 896 * XXX anything in the data path that needs to be considered? 897 */ 898 ofp->ssthresh = ofp->cwnd / 2; 899 if (ofp->ssthresh < 2 * ofp->sfa_pmss) 900 ofp->ssthresh = 2 * ofp->sfa_pmss; 901 ofp->cwnd = ofp->sfa_pmss; 902 ofp->pba = 0; 903 ofp->suna -= MBLKL(sctp->sctp_cxmit_list); 904 /* 905 * The rexmit flags is used to determine if a serial number needs to 906 * be assigned or not, so once set we leave it there. 907 */ 908 if (!SCTP_CHUNK_WANT_REXMIT(sctp->sctp_cxmit_list)) 909 SCTP_CHUNK_REXMIT(sctp->sctp_cxmit_list); 910 sctp_wput_asconf(sctp, nfp); 911 #undef SCTP_CLR_SENT_FLAG 912 } 913 914 void 915 sctp_wput_asconf(sctp_t *sctp, sctp_faddr_t *fp) 916 { 917 #define SCTP_SET_SENT_FLAG(mp) ((mp)->b_flag = SCTP_CHUNK_FLAG_SENT) 918 919 mblk_t *mp; 920 mblk_t *ipmp; 921 uint32_t *snp; 922 sctp_parm_hdr_t *ph; 923 boolean_t isv4; 924 sctp_stack_t *sctps = sctp->sctp_sctps; 925 boolean_t saddr_set; 926 927 if (sctp->sctp_cchunk_pend || sctp->sctp_cxmit_list == NULL || 928 /* Queue it for later transmission if not yet established */ 929 sctp->sctp_state < SCTPS_ESTABLISHED) { 930 ip2dbg(("sctp_wput_asconf: cchunk pending? (%d) or null "\ 931 "sctp_cxmit_list? (%s) or incorrect state? (%x)\n", 932 sctp->sctp_cchunk_pend, sctp->sctp_cxmit_list == NULL ? 933 "yes" : "no", sctp->sctp_state)); 934 return; 935 } 936 937 if (fp == NULL) 938 fp = sctp->sctp_current; 939 940 /* OK to send */ 941 ipmp = sctp_make_mp(sctp, fp, 0); 942 if (ipmp == NULL) { 943 SCTP_FADDR_RC_TIMER_RESTART(sctp, fp, fp->rto); 944 SCTP_KSTAT(sctps, sctp_send_asconf_failed); 945 return; 946 } 947 mp = sctp->sctp_cxmit_list; 948 /* Fill in the mandatory Address Parameter TLV */ 949 isv4 = (fp != NULL) ? fp->isv4 : sctp->sctp_current->isv4; 950 ph = (sctp_parm_hdr_t *)(mp->b_rptr + sizeof (sctp_chunk_hdr_t) + 951 sizeof (uint32_t)); 952 if (isv4) { 953 ipha_t *ipha = (ipha_t *)ipmp->b_rptr; 954 in6_addr_t ipaddr; 955 ipaddr_t addr4; 956 957 ph->sph_type = htons(PARM_ADDR4); 958 ph->sph_len = htons(PARM_ADDR4_LEN); 959 if (ipha->ipha_src != INADDR_ANY) { 960 bcopy(&ipha->ipha_src, ph + 1, IP_ADDR_LEN); 961 } else { 962 ipaddr = sctp_get_valid_addr(sctp, B_FALSE, &saddr_set); 963 /* 964 * All the addresses are down. 965 * Maybe we might have better luck next time. 966 */ 967 if (!saddr_set) { 968 SCTP_FADDR_RC_TIMER_RESTART(sctp, fp, fp->rto); 969 freeb(ipmp); 970 return; 971 } 972 IN6_V4MAPPED_TO_IPADDR(&ipaddr, addr4); 973 bcopy(&addr4, ph + 1, IP_ADDR_LEN); 974 } 975 } else { 976 ip6_t *ip6 = (ip6_t *)ipmp->b_rptr; 977 in6_addr_t ipaddr; 978 979 ph->sph_type = htons(PARM_ADDR6); 980 ph->sph_len = htons(PARM_ADDR6_LEN); 981 if (!IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_src)) { 982 bcopy(&ip6->ip6_src, ph + 1, IPV6_ADDR_LEN); 983 } else { 984 ipaddr = sctp_get_valid_addr(sctp, B_TRUE, &saddr_set); 985 /* 986 * All the addresses are down. 987 * Maybe we might have better luck next time. 988 */ 989 if (!saddr_set) { 990 SCTP_FADDR_RC_TIMER_RESTART(sctp, fp, fp->rto); 991 freeb(ipmp); 992 return; 993 } 994 bcopy(&ipaddr, ph + 1, IPV6_ADDR_LEN); 995 } 996 } 997 998 /* Don't exceed CWND */ 999 if ((MBLKL(mp) > (fp->cwnd - fp->suna)) || 1000 ((mp = dupb(sctp->sctp_cxmit_list)) == NULL)) { 1001 SCTP_FADDR_RC_TIMER_RESTART(sctp, fp, fp->rto); 1002 freeb(ipmp); 1003 return; 1004 } 1005 1006 /* Set the serial number now, if sending for the first time */ 1007 if (!SCTP_CHUNK_WANT_REXMIT(mp)) { 1008 snp = (uint32_t *)(mp->b_rptr + sizeof (sctp_chunk_hdr_t)); 1009 *snp = htonl(sctp->sctp_lcsn++); 1010 } 1011 SCTP_CHUNK_CLEAR_FLAGS(mp); 1012 fp->suna += MBLKL(mp); 1013 /* Attach the header and send the chunk */ 1014 ipmp->b_cont = mp; 1015 sctp->sctp_cchunk_pend = 1; 1016 1017 SCTP_SET_SENT_FLAG(sctp->sctp_cxmit_list); 1018 SCTP_SET_CHUNK_DEST(sctp->sctp_cxmit_list, fp); 1019 sctp_set_iplen(sctp, ipmp, fp->ixa); 1020 (void) conn_ip_output(ipmp, fp->ixa); 1021 BUMP_LOCAL(sctp->sctp_opkts); 1022 SCTP_FADDR_RC_TIMER_RESTART(sctp, fp, fp->rto); 1023 #undef SCTP_SET_SENT_FLAG 1024 } 1025 1026 /* 1027 * Generate ASCONF error param, include errph, if present. 1028 */ 1029 static mblk_t * 1030 sctp_asconf_adderr(int err, sctp_parm_hdr_t *errph, uint32_t cid) 1031 { 1032 mblk_t *mp; 1033 sctp_parm_hdr_t *eph; 1034 sctp_parm_hdr_t *wph; 1035 size_t len; 1036 size_t elen = 0; 1037 1038 len = sizeof (*wph) + sizeof (*eph) + sizeof (cid); 1039 if (errph != NULL) { 1040 elen = ntohs(errph->sph_len); 1041 len += elen; 1042 } 1043 mp = allocb(len, BPRI_MED); 1044 if (mp == NULL) { 1045 return (NULL); 1046 } 1047 wph = (sctp_parm_hdr_t *)mp->b_rptr; 1048 /* error cause wrapper */ 1049 wph->sph_type = htons(PARM_ERROR_IND); 1050 wph->sph_len = htons(len); 1051 bcopy(&cid, wph + 1, sizeof (uint32_t)); 1052 1053 /* error cause */ 1054 eph = (sctp_parm_hdr_t *)((char *)wph + sizeof (sctp_parm_hdr_t) + 1055 sizeof (cid)); 1056 eph->sph_type = htons(err); 1057 eph->sph_len = htons(len - sizeof (*wph) - sizeof (cid)); 1058 mp->b_wptr = (uchar_t *)(eph + 1); 1059 1060 /* details */ 1061 if (elen > 0) { 1062 bcopy(errph, mp->b_wptr, elen); 1063 mp->b_wptr += elen; 1064 } 1065 return (mp); 1066 } 1067 1068 static mblk_t * 1069 sctp_check_addip_addr(sctp_parm_hdr_t *ph, sctp_parm_hdr_t *oph, int *cont, 1070 uint32_t cid, in6_addr_t *raddr) 1071 { 1072 uint16_t atype; 1073 uint16_t alen; 1074 mblk_t *mp; 1075 in6_addr_t addr; 1076 ipaddr_t *addr4; 1077 1078 atype = ntohs(ph->sph_type); 1079 alen = ntohs(ph->sph_len); 1080 1081 if (atype != PARM_ADDR4 && atype != PARM_ADDR6) { 1082 mp = sctp_asconf_adderr(SCTP_ERR_BAD_MANDPARM, oph, cid); 1083 if (mp == NULL) { 1084 *cont = -1; 1085 } 1086 return (mp); 1087 } 1088 if ((atype == PARM_ADDR4 && alen < PARM_ADDR4_LEN) || 1089 (atype == PARM_ADDR6 && alen < PARM_ADDR6_LEN)) { 1090 mp = sctp_asconf_adderr(SCTP_ERR_BAD_MANDPARM, oph, cid); 1091 if (mp == NULL) { 1092 *cont = -1; 1093 } 1094 return (mp); 1095 } 1096 1097 /* Address parameter is present; extract and screen it */ 1098 if (atype == PARM_ADDR4) { 1099 addr4 = (ipaddr_t *)(ph + 1); 1100 IN6_IPADDR_TO_V4MAPPED(*addr4, &addr); 1101 1102 /* screen XXX loopback to scoping */ 1103 if (*addr4 == 0 || *addr4 == INADDR_BROADCAST || 1104 *addr4 == htonl(INADDR_LOOPBACK) || CLASSD(*addr4)) { 1105 dprint(1, ("addip: addr not unicast: %x:%x:%x:%x\n", 1106 SCTP_PRINTADDR(addr))); 1107 mp = sctp_asconf_adderr(SCTP_ERR_BAD_MANDPARM, oph, 1108 cid); 1109 if (mp == NULL) { 1110 *cont = -1; 1111 } 1112 return (mp); 1113 } 1114 /* 1115 * XXX also need to check for subnet 1116 * broadcasts. This should probably 1117 * wait until we have full access 1118 * to the ILL tables. 1119 */ 1120 1121 } else { 1122 bcopy(ph + 1, &addr, sizeof (addr)); 1123 1124 /* screen XXX loopback to scoping */ 1125 if (IN6_IS_ADDR_LINKLOCAL(&addr) || 1126 IN6_IS_ADDR_MULTICAST(&addr) || 1127 IN6_IS_ADDR_LOOPBACK(&addr)) { 1128 dprint(1, ("addip: addr not unicast: %x:%x:%x:%x\n", 1129 SCTP_PRINTADDR(addr))); 1130 mp = sctp_asconf_adderr(SCTP_ERR_BAD_MANDPARM, oph, 1131 cid); 1132 if (mp == NULL) { 1133 *cont = -1; 1134 } 1135 return (mp); 1136 } 1137 1138 } 1139 1140 /* OK */ 1141 *raddr = addr; 1142 return (NULL); 1143 } 1144 1145 /* 1146 * Handles both add and delete address requests. 1147 */ 1148 static mblk_t * 1149 sctp_addip_req(sctp_t *sctp, sctp_parm_hdr_t *ph, uint32_t cid, 1150 sctp_faddr_t *fp, int *cont, int act, in6_addr_t *raddr) 1151 { 1152 in6_addr_t addr; 1153 uint16_t type; 1154 mblk_t *mp; 1155 sctp_faddr_t *nfp; 1156 sctp_parm_hdr_t *oph = ph; 1157 int err; 1158 sctp_stack_t *sctps = sctp->sctp_sctps; 1159 1160 *cont = 1; 1161 1162 /* Send back an authorization error if addip is disabled */ 1163 if (!sctps->sctps_addip_enabled) { 1164 err = SCTP_ERR_UNAUTHORIZED; 1165 goto error_handler; 1166 } 1167 /* Check input */ 1168 if (ntohs(ph->sph_len) < (sizeof (*ph) * 2)) { 1169 err = SCTP_ERR_BAD_MANDPARM; 1170 goto error_handler; 1171 } 1172 1173 type = ntohs(ph->sph_type); 1174 ph = (sctp_parm_hdr_t *)((char *)ph + sizeof (sctp_parm_hdr_t) + 1175 sizeof (cid)); 1176 mp = sctp_check_addip_addr(ph, oph, cont, cid, &addr); 1177 if (mp != NULL) 1178 return (mp); 1179 if (raddr != NULL) 1180 *raddr = addr; 1181 if (type == PARM_ADD_IP) { 1182 if (sctp_lookup_faddr(sctp, &addr) != NULL) { 1183 /* Address is already part of association */ 1184 dprint(1, ("addip: addr already here: %x:%x:%x:%x\n", 1185 SCTP_PRINTADDR(addr))); 1186 err = SCTP_ERR_BAD_MANDPARM; 1187 goto error_handler; 1188 } 1189 1190 if (!act) { 1191 return (NULL); 1192 } 1193 /* Add the new address */ 1194 mutex_enter(&sctp->sctp_conn_tfp->tf_lock); 1195 err = sctp_add_faddr(sctp, &addr, KM_NOSLEEP, B_FALSE); 1196 mutex_exit(&sctp->sctp_conn_tfp->tf_lock); 1197 if (err == ENOMEM) { 1198 /* no memory */ 1199 *cont = -1; 1200 return (NULL); 1201 } 1202 if (err != 0) { 1203 err = SCTP_ERR_BAD_MANDPARM; 1204 goto error_handler; 1205 } 1206 sctp_intf_event(sctp, addr, SCTP_ADDR_ADDED, 0); 1207 } else if (type == PARM_DEL_IP) { 1208 nfp = sctp_lookup_faddr(sctp, &addr); 1209 if (nfp == NULL) { 1210 /* 1211 * Peer is trying to delete an address that is not 1212 * part of the association. 1213 */ 1214 dprint(1, ("delip: addr not here: %x:%x:%x:%x\n", 1215 SCTP_PRINTADDR(addr))); 1216 err = SCTP_ERR_BAD_MANDPARM; 1217 goto error_handler; 1218 } 1219 if (sctp->sctp_faddrs == nfp && nfp->next == NULL) { 1220 /* Peer is trying to delete last address */ 1221 dprint(1, ("delip: del last addr: %x:%x:%x:%x\n", 1222 SCTP_PRINTADDR(addr))); 1223 err = SCTP_ERR_DEL_LAST_ADDR; 1224 goto error_handler; 1225 } 1226 if (nfp == fp) { 1227 /* Peer is trying to delete source address */ 1228 dprint(1, ("delip: del src addr: %x:%x:%x:%x\n", 1229 SCTP_PRINTADDR(addr))); 1230 err = SCTP_ERR_DEL_SRC_ADDR; 1231 goto error_handler; 1232 } 1233 if (!act) { 1234 return (NULL); 1235 } 1236 1237 sctp_unlink_faddr(sctp, nfp); 1238 /* Update all references to the deleted faddr */ 1239 if (sctp->sctp_primary == nfp) { 1240 sctp->sctp_primary = fp; 1241 } 1242 if (sctp->sctp_current == nfp) { 1243 sctp_set_faddr_current(sctp, fp); 1244 } 1245 if (sctp->sctp_lastdata == nfp) { 1246 sctp->sctp_lastdata = fp; 1247 } 1248 if (sctp->sctp_shutdown_faddr == nfp) { 1249 sctp->sctp_shutdown_faddr = nfp; 1250 } 1251 if (sctp->sctp_lastfaddr == nfp) { 1252 for (fp = sctp->sctp_faddrs; fp->next; fp = fp->next) 1253 ; 1254 sctp->sctp_lastfaddr = fp; 1255 } 1256 sctp_intf_event(sctp, addr, SCTP_ADDR_REMOVED, 0); 1257 } else { 1258 ASSERT(0); 1259 } 1260 1261 /* Successful, don't need to return anything. */ 1262 return (NULL); 1263 1264 error_handler: 1265 mp = sctp_asconf_adderr(err, oph, cid); 1266 if (mp == NULL) 1267 *cont = -1; 1268 return (mp); 1269 } 1270 1271 /* 1272 * Handles both add and delete IP ACKs. 1273 */ 1274 /*ARGSUSED*/ 1275 static void 1276 sctp_addip_ack(sctp_t *sctp, sctp_parm_hdr_t *ph, sctp_parm_hdr_t *oph, 1277 sctp_faddr_t *fp, in6_addr_t *laddr) 1278 { 1279 in6_addr_t addr; 1280 sctp_saddr_ipif_t *sp; 1281 ipaddr_t *addr4; 1282 boolean_t backout = B_FALSE; 1283 uint16_t type; 1284 uint32_t *cid; 1285 1286 /* could be an ASSERT */ 1287 if (laddr != NULL) 1288 IN6_IPADDR_TO_V4MAPPED(0, laddr); 1289 1290 /* If the peer doesn't understand Add-IP, remember it */ 1291 if (ph != NULL && ph->sph_type == htons(PARM_UNRECOGNIZED)) { 1292 sctp->sctp_understands_addip = B_FALSE; 1293 backout = B_TRUE; 1294 } 1295 1296 /* 1297 * If OK, continue with the add / delete action, otherwise 1298 * back out the action. 1299 */ 1300 if (ph != NULL && ph->sph_type != htons(PARM_SUCCESS)) { 1301 backout = B_TRUE; 1302 sctp_error_event(sctp, (sctp_chunk_hdr_t *)ph, B_TRUE); 1303 } 1304 1305 type = ntohs(oph->sph_type); 1306 cid = (uint32_t *)(oph + 1); 1307 oph = (sctp_parm_hdr_t *)(cid + 1); 1308 if (oph->sph_type == htons(PARM_ADDR4)) { 1309 addr4 = (ipaddr_t *)(oph + 1); 1310 IN6_IPADDR_TO_V4MAPPED(*addr4, &addr); 1311 } else { 1312 bcopy(oph + 1, &addr, sizeof (addr)); 1313 } 1314 1315 /* Signifies that the address was sucessfully processed */ 1316 if (!backout && laddr != NULL) 1317 *laddr = addr; 1318 1319 sp = sctp_saddr_lookup(sctp, &addr, 0); 1320 ASSERT(sp != NULL); 1321 1322 if (type == PARM_ADD_IP) { 1323 if (backout) { 1324 sctp_del_saddr(sctp, sp); 1325 } else { 1326 sp->saddr_ipif_dontsrc = 0; 1327 } 1328 } else if (type == PARM_DEL_IP) { 1329 if (backout) { 1330 sp->saddr_ipif_delete_pending = 0; 1331 sp->saddr_ipif_dontsrc = 0; 1332 } else { 1333 sctp_del_saddr(sctp, sp); 1334 } 1335 } else { 1336 /* Must be either PARM_ADD_IP or PARM_DEL_IP */ 1337 ASSERT(0); 1338 } 1339 } 1340 1341 /*ARGSUSED*/ 1342 static mblk_t * 1343 sctp_setprim_req(sctp_t *sctp, sctp_parm_hdr_t *ph, uint32_t cid, 1344 sctp_faddr_t *fp, int *cont, int act, in6_addr_t *raddr) 1345 { 1346 mblk_t *mp; 1347 sctp_parm_hdr_t *oph; 1348 sctp_faddr_t *nfp; 1349 in6_addr_t addr; 1350 1351 *cont = 1; 1352 1353 /* Does the peer understand ASCONF and Add-IP? */ 1354 if (!sctp->sctp_understands_asconf || !sctp->sctp_understands_addip) { 1355 mp = sctp_asconf_adderr(SCTP_ERR_UNAUTHORIZED, ph, cid); 1356 if (mp == NULL) { 1357 *cont = -1; 1358 } 1359 return (mp); 1360 } 1361 1362 /* Check input */ 1363 if (ntohs(ph->sph_len) < (sizeof (*ph) * 2)) { 1364 mp = sctp_asconf_adderr(SCTP_ERR_BAD_MANDPARM, ph, cid); 1365 if (mp == NULL) { 1366 *cont = -1; 1367 } 1368 return (mp); 1369 } 1370 1371 oph = ph; 1372 ph = (sctp_parm_hdr_t *)((char *)ph + sizeof (sctp_parm_hdr_t) + 1373 sizeof (cid)); 1374 mp = sctp_check_addip_addr(ph, oph, cont, cid, &addr); 1375 if (mp != NULL) { 1376 return (mp); 1377 } 1378 1379 nfp = sctp_lookup_faddr(sctp, &addr); 1380 if (nfp == NULL) { 1381 /* 1382 * Peer is trying to set an address that is not 1383 * part of the association. 1384 */ 1385 dprint(1, ("setprim: addr not here: %x:%x:%x:%x\n", 1386 SCTP_PRINTADDR(addr))); 1387 mp = sctp_asconf_adderr(SCTP_ERR_BAD_MANDPARM, oph, cid); 1388 if (mp == NULL) { 1389 *cont = -1; 1390 } 1391 return (mp); 1392 } 1393 1394 sctp_intf_event(sctp, addr, SCTP_ADDR_MADE_PRIM, 0); 1395 sctp->sctp_primary = nfp; 1396 if (nfp->state != SCTP_FADDRS_ALIVE || nfp == sctp->sctp_current) { 1397 return (NULL); 1398 } 1399 sctp_set_faddr_current(sctp, nfp); 1400 return (NULL); 1401 } 1402 1403 /*ARGSUSED*/ 1404 static void 1405 sctp_setprim_ack(sctp_t *sctp, sctp_parm_hdr_t *ph, sctp_parm_hdr_t *oph, 1406 sctp_faddr_t *fp, in6_addr_t *laddr) 1407 { 1408 if (ph != NULL && ph->sph_type != htons(PARM_SUCCESS)) { 1409 /* If the peer doesn't understand Add-IP, remember it */ 1410 if (ph->sph_type == htons(PARM_UNRECOGNIZED)) { 1411 sctp->sctp_understands_addip = B_FALSE; 1412 } 1413 sctp_error_event(sctp, (sctp_chunk_hdr_t *)ph, B_TRUE); 1414 } 1415 1416 /* On success we do nothing */ 1417 } 1418 1419 int 1420 sctp_add_ip(sctp_t *sctp, const void *addrs, uint32_t cnt) 1421 { 1422 struct sockaddr_in *sin4; 1423 struct sockaddr_in6 *sin6; 1424 mblk_t *mp; 1425 int error = 0; 1426 int i; 1427 sctp_addip4_t *ad4; 1428 sctp_addip6_t *ad6; 1429 sctp_asconf_t asc[1]; 1430 uint16_t type = htons(PARM_ADD_IP); 1431 boolean_t v4mapped = B_FALSE; 1432 sctp_cl_ainfo_t *ainfo = NULL; 1433 conn_t *connp = sctp->sctp_connp; 1434 1435 /* Does the peer understand ASCONF and Add-IP? */ 1436 if (!sctp->sctp_understands_asconf || !sctp->sctp_understands_addip) 1437 return (EOPNOTSUPP); 1438 1439 /* 1440 * On a clustered node, we need to pass this list when 1441 * we get an ASCONF-ACK. We only pre-allocate memory for the 1442 * list, but fill in the addresses when it is processed 1443 * successfully after we get an ASCONF-ACK. 1444 */ 1445 if (cl_sctp_assoc_change != NULL) { 1446 ainfo = kmem_zalloc(sizeof (*ainfo), KM_SLEEP); 1447 /* 1448 * Reserve space for the list of new addresses 1449 */ 1450 ainfo->sctp_cl_asize = sizeof (in6_addr_t) * cnt; 1451 ainfo->sctp_cl_alist = kmem_alloc(ainfo->sctp_cl_asize, 1452 KM_SLEEP); 1453 } 1454 1455 sctp_asconf_init(asc); 1456 1457 /* 1458 * Screen addresses: 1459 * If adding: 1460 * o Must not already be a part of the association 1461 * o Must be AF_INET or AF_INET6 1462 * o XXX Must be valid source address for this node 1463 * o Must be unicast 1464 * o XXX Must fit scoping rules 1465 * If deleting: 1466 * o Must be part of the association 1467 */ 1468 for (i = 0; i < cnt; i++) { 1469 switch (connp->conn_family) { 1470 case AF_INET: 1471 sin4 = (struct sockaddr_in *)addrs + i; 1472 v4mapped = B_TRUE; 1473 break; 1474 1475 case AF_INET6: 1476 sin6 = (struct sockaddr_in6 *)addrs + i; 1477 break; 1478 } 1479 1480 if (v4mapped) { 1481 mp = allocb(sizeof (*ad4), BPRI_MED); 1482 if (mp == NULL) { 1483 error = ENOMEM; 1484 goto fail; 1485 } 1486 mp->b_wptr += sizeof (*ad4); 1487 ad4 = (sctp_addip4_t *)mp->b_rptr; 1488 ad4->sad4_addip_ph.sph_type = type; 1489 ad4->sad4_addip_ph.sph_len = 1490 htons(sizeof (sctp_parm_hdr_t) + 1491 PARM_ADDR4_LEN + sizeof (ad4->asconf_req_cid)); 1492 ad4->sad4_addr4_ph.sph_type = htons(PARM_ADDR4); 1493 ad4->sad4_addr4_ph.sph_len = htons(PARM_ADDR4_LEN); 1494 ad4->sad4_addr = sin4->sin_addr.s_addr; 1495 } else { 1496 mp = allocb(sizeof (*ad6), BPRI_MED); 1497 if (mp == NULL) { 1498 error = ENOMEM; 1499 goto fail; 1500 } 1501 mp->b_wptr += sizeof (*ad6); 1502 ad6 = (sctp_addip6_t *)mp->b_rptr; 1503 ad6->sad6_addip_ph.sph_type = type; 1504 ad6->sad6_addip_ph.sph_len = 1505 htons(sizeof (sctp_parm_hdr_t) + 1506 PARM_ADDR6_LEN + sizeof (ad6->asconf_req_cid)); 1507 ad6->sad6_addr6_ph.sph_type = htons(PARM_ADDR6); 1508 ad6->sad6_addr6_ph.sph_len = htons(PARM_ADDR6_LEN); 1509 ad6->sad6_addr = sin6->sin6_addr; 1510 } 1511 error = sctp_asconf_add(asc, mp); 1512 if (error != 0) 1513 goto fail; 1514 } 1515 error = sctp_asconf_send(sctp, asc, sctp->sctp_current, ainfo); 1516 if (error != 0) 1517 goto fail; 1518 1519 return (0); 1520 1521 fail: 1522 if (ainfo != NULL) { 1523 kmem_free(ainfo->sctp_cl_alist, ainfo->sctp_cl_asize); 1524 ainfo->sctp_cl_asize = 0; 1525 kmem_free(ainfo, sizeof (*ainfo)); 1526 } 1527 sctp_asconf_destroy(asc); 1528 return (error); 1529 } 1530 1531 int 1532 sctp_del_ip(sctp_t *sctp, const void *addrs, uint32_t cnt, uchar_t *ulist, 1533 size_t usize) 1534 { 1535 struct sockaddr_in *sin4; 1536 struct sockaddr_in6 *sin6; 1537 mblk_t *mp; 1538 int error = 0; 1539 int i; 1540 int addrcnt = 0; 1541 sctp_addip4_t *ad4; 1542 sctp_addip6_t *ad6; 1543 sctp_asconf_t asc[1]; 1544 sctp_saddr_ipif_t *nsp; 1545 uint16_t type = htons(PARM_DEL_IP); 1546 boolean_t v4mapped = B_FALSE; 1547 in6_addr_t addr; 1548 boolean_t asconf = B_TRUE; 1549 uint_t ifindex; 1550 sctp_cl_ainfo_t *ainfo = NULL; 1551 uchar_t *p = ulist; 1552 boolean_t check_lport = B_FALSE; 1553 sctp_stack_t *sctps = sctp->sctp_sctps; 1554 conn_t *connp = sctp->sctp_connp; 1555 1556 /* Does the peer understand ASCONF and Add-IP? */ 1557 if (sctp->sctp_state <= SCTPS_LISTEN || !sctps->sctps_addip_enabled || 1558 !sctp->sctp_understands_asconf || !sctp->sctp_understands_addip) { 1559 asconf = B_FALSE; 1560 } 1561 1562 if (sctp->sctp_state > SCTPS_BOUND) 1563 check_lport = B_TRUE; 1564 1565 if (asconf) { 1566 /* 1567 * On a clustered node, we need to pass this list when 1568 * we get an ASCONF-ACK. We only pre-allocate memory for the 1569 * list, but fill in the addresses when it is processed 1570 * successfully after we get an ASCONF-ACK. 1571 */ 1572 if (cl_sctp_assoc_change != NULL) { 1573 ainfo = kmem_alloc(sizeof (*ainfo), KM_SLEEP); 1574 ainfo->sctp_cl_dsize = sizeof (in6_addr_t) * cnt; 1575 ainfo->sctp_cl_dlist = kmem_alloc(ainfo->sctp_cl_dsize, 1576 KM_SLEEP); 1577 } 1578 sctp_asconf_init(asc); 1579 } 1580 /* 1581 * Screen addresses: 1582 * If adding: 1583 * o Must not already be a part of the association 1584 * o Must be AF_INET or AF_INET6 1585 * o XXX Must be valid source address for this node 1586 * o Must be unicast 1587 * o XXX Must fit scoping rules 1588 * If deleting: 1589 * o Must be part of the association 1590 */ 1591 for (i = 0; i < cnt; i++) { 1592 ifindex = 0; 1593 1594 switch (connp->conn_family) { 1595 case AF_INET: 1596 sin4 = (struct sockaddr_in *)addrs + i; 1597 if (check_lport && 1598 sin4->sin_port != connp->conn_lport) { 1599 error = EINVAL; 1600 goto fail; 1601 } 1602 v4mapped = B_TRUE; 1603 IN6_IPADDR_TO_V4MAPPED(sin4->sin_addr.s_addr, &addr); 1604 break; 1605 1606 case AF_INET6: 1607 sin6 = (struct sockaddr_in6 *)addrs + i; 1608 if (check_lport && 1609 sin6->sin6_port != connp->conn_lport) { 1610 error = EINVAL; 1611 goto fail; 1612 } 1613 addr = sin6->sin6_addr; 1614 ifindex = sin6->sin6_scope_id; 1615 break; 1616 } 1617 nsp = sctp_saddr_lookup(sctp, &addr, ifindex); 1618 if (nsp == NULL) { 1619 error = EADDRNOTAVAIL; 1620 goto fail; 1621 } 1622 1623 /* Collect the list of addresses, if required */ 1624 if (usize >= sizeof (addr)) { 1625 bcopy(&addr, p, sizeof (addr)); 1626 p += sizeof (addr); 1627 usize -= sizeof (addr); 1628 } 1629 if (!asconf) 1630 continue; 1631 1632 nsp->saddr_ipif_delete_pending = 1; 1633 nsp->saddr_ipif_dontsrc = 1; 1634 addrcnt++; 1635 if (v4mapped) { 1636 mp = allocb(sizeof (*ad4), BPRI_MED); 1637 if (mp == NULL) { 1638 error = ENOMEM; 1639 goto fail; 1640 } 1641 mp->b_wptr += sizeof (*ad4); 1642 ad4 = (sctp_addip4_t *)mp->b_rptr; 1643 ad4->sad4_addip_ph.sph_type = type; 1644 ad4->sad4_addip_ph.sph_len = 1645 htons(sizeof (sctp_parm_hdr_t) + 1646 PARM_ADDR4_LEN + sizeof (ad4->asconf_req_cid)); 1647 ad4->sad4_addr4_ph.sph_type = htons(PARM_ADDR4); 1648 ad4->sad4_addr4_ph.sph_len = htons(PARM_ADDR4_LEN); 1649 ad4->sad4_addr = sin4->sin_addr.s_addr; 1650 } else { 1651 mp = allocb(sizeof (*ad6), BPRI_MED); 1652 if (mp == NULL) { 1653 error = ENOMEM; 1654 goto fail; 1655 } 1656 mp->b_wptr += sizeof (*ad6); 1657 ad6 = (sctp_addip6_t *)mp->b_rptr; 1658 ad6->sad6_addip_ph.sph_type = type; 1659 ad6->sad6_addip_ph.sph_len = 1660 htons(sizeof (sctp_parm_hdr_t) + PARM_ADDR6_LEN + 1661 sizeof (ad6->asconf_req_cid)); 1662 ad6->sad6_addr6_ph.sph_type = htons(PARM_ADDR6); 1663 ad6->sad6_addr6_ph.sph_len = htons(PARM_ADDR6_LEN); 1664 ad6->sad6_addr = addr; 1665 } 1666 1667 error = sctp_asconf_add(asc, mp); 1668 if (error != 0) 1669 goto fail; 1670 } 1671 1672 if (!asconf) { 1673 sctp_del_saddr_list(sctp, addrs, cnt, B_FALSE); 1674 return (0); 1675 } 1676 error = sctp_asconf_send(sctp, asc, sctp->sctp_current, ainfo); 1677 if (error != 0) 1678 goto fail; 1679 sctp_redo_faddr_srcs(sctp); 1680 return (0); 1681 1682 fail: 1683 if (ainfo != NULL) { 1684 kmem_free(ainfo->sctp_cl_dlist, ainfo->sctp_cl_dsize); 1685 ainfo->sctp_cl_dsize = 0; 1686 kmem_free(ainfo, sizeof (*ainfo)); 1687 } 1688 if (!asconf) 1689 return (error); 1690 for (i = 0; i < addrcnt; i++) { 1691 ifindex = 0; 1692 1693 switch (connp->conn_family) { 1694 case AF_INET: 1695 sin4 = (struct sockaddr_in *)addrs + i; 1696 IN6_INADDR_TO_V4MAPPED(&(sin4->sin_addr), &addr); 1697 break; 1698 case AF_INET6: 1699 sin6 = (struct sockaddr_in6 *)addrs + i; 1700 addr = sin6->sin6_addr; 1701 ifindex = sin6->sin6_scope_id; 1702 break; 1703 } 1704 nsp = sctp_saddr_lookup(sctp, &addr, ifindex); 1705 ASSERT(nsp != NULL); 1706 nsp->saddr_ipif_delete_pending = 0; 1707 nsp->saddr_ipif_dontsrc = 0; 1708 } 1709 sctp_asconf_destroy(asc); 1710 1711 return (error); 1712 } 1713 1714 int 1715 sctp_set_peerprim(sctp_t *sctp, const void *inp) 1716 { 1717 const struct sctp_setprim *prim = inp; 1718 const struct sockaddr_storage *ss; 1719 struct sockaddr_in *sin; 1720 struct sockaddr_in6 *sin6; 1721 in6_addr_t addr; 1722 mblk_t *mp; 1723 sctp_saddr_ipif_t *sp; 1724 sctp_addip4_t *ad4; 1725 sctp_addip6_t *ad6; 1726 sctp_asconf_t asc[1]; 1727 int error = 0; 1728 uint_t ifindex = 0; 1729 1730 /* Does the peer understand ASCONF and Add-IP? */ 1731 if (!sctp->sctp_understands_asconf || !sctp->sctp_understands_addip) { 1732 return (EOPNOTSUPP); 1733 } 1734 1735 /* Don't do anything if we are not connected */ 1736 if (sctp->sctp_state != SCTPS_ESTABLISHED) 1737 return (EINVAL); 1738 1739 ss = &prim->ssp_addr; 1740 sin = NULL; 1741 sin6 = NULL; 1742 if (ss->ss_family == AF_INET) { 1743 sin = (struct sockaddr_in *)ss; 1744 IN6_IPADDR_TO_V4MAPPED(sin->sin_addr.s_addr, &addr); 1745 } else if (ss->ss_family == AF_INET6) { 1746 sin6 = (struct sockaddr_in6 *)ss; 1747 addr = sin6->sin6_addr; 1748 ifindex = sin6->sin6_scope_id; 1749 } else { 1750 return (EAFNOSUPPORT); 1751 } 1752 sp = sctp_saddr_lookup(sctp, &addr, ifindex); 1753 if (sp == NULL) 1754 return (EADDRNOTAVAIL); 1755 sctp_asconf_init(asc); 1756 if (sin) { 1757 mp = allocb(sizeof (*ad4), BPRI_MED); 1758 if (mp == NULL) { 1759 error = ENOMEM; 1760 goto fail; 1761 } 1762 mp->b_wptr += sizeof (*ad4); 1763 ad4 = (sctp_addip4_t *)mp->b_rptr; 1764 ad4->sad4_addip_ph.sph_type = htons(PARM_SET_PRIMARY); 1765 ad4->sad4_addip_ph.sph_len = htons(sizeof (sctp_parm_hdr_t) + 1766 PARM_ADDR4_LEN + sizeof (ad4->asconf_req_cid)); 1767 ad4->sad4_addr4_ph.sph_type = htons(PARM_ADDR4); 1768 ad4->sad4_addr4_ph.sph_len = htons(PARM_ADDR4_LEN); 1769 ad4->sad4_addr = sin->sin_addr.s_addr; 1770 } else { 1771 mp = allocb(sizeof (*ad6), BPRI_MED); 1772 if (mp == NULL) { 1773 error = ENOMEM; 1774 goto fail; 1775 } 1776 mp->b_wptr += sizeof (*ad6); 1777 ad6 = (sctp_addip6_t *)mp->b_rptr; 1778 ad6->sad6_addip_ph.sph_type = htons(PARM_SET_PRIMARY); 1779 ad6->sad6_addip_ph.sph_len = htons(sizeof (sctp_parm_hdr_t) + 1780 PARM_ADDR6_LEN + sizeof (ad6->asconf_req_cid)); 1781 ad6->sad6_addr6_ph.sph_type = htons(PARM_ADDR6); 1782 ad6->sad6_addr6_ph.sph_len = htons(PARM_ADDR6_LEN); 1783 ad6->sad6_addr = sin6->sin6_addr; 1784 } 1785 1786 error = sctp_asconf_add(asc, mp); 1787 if (error != 0) { 1788 goto fail; 1789 } 1790 1791 error = sctp_asconf_send(sctp, asc, sctp->sctp_current, NULL); 1792 if (error == 0) { 1793 return (0); 1794 } 1795 1796 fail: 1797 sctp_asconf_destroy(asc); 1798 return (error); 1799 } 1800