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