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