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