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