Home | History | Annotate | Download | only in sctp
      1      0    stevel /*
      2      0    stevel  * CDDL HEADER START
      3      0    stevel  *
      4      0    stevel  * The contents of this file are subject to the terms of the
      5   1676       jpk  * Common Development and Distribution License (the "License").
      6   1676       jpk  * You may not use this file except in compliance with the License.
      7      0    stevel  *
      8      0    stevel  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9      0    stevel  * or http://www.opensolaris.org/os/licensing.
     10      0    stevel  * See the License for the specific language governing permissions
     11      0    stevel  * and limitations under the License.
     12      0    stevel  *
     13      0    stevel  * When distributing Covered Code, include this CDDL HEADER in each
     14      0    stevel  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15      0    stevel  * If applicable, add the following below this CDDL HEADER, with the
     16      0    stevel  * fields enclosed by brackets "[]" replaced with your own identifying
     17      0    stevel  * information: Portions Copyright [yyyy] [name of copyright owner]
     18      0    stevel  *
     19      0    stevel  * CDDL HEADER END
     20      0    stevel  */
     21   1735    kcpoon 
     22      0    stevel /*
     23   8549    George  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
     24      0    stevel  * Use is subject to license terms.
     25      0    stevel  */
     26      0    stevel 
     27      0    stevel #include <sys/types.h>
     28      0    stevel #include <sys/systm.h>
     29      0    stevel #include <sys/stream.h>
     30   1676       jpk #include <sys/strsubr.h>
     31      0    stevel #include <sys/ddi.h>
     32      0    stevel #include <sys/sunddi.h>
     33      0    stevel #include <sys/kmem.h>
     34      0    stevel #include <sys/socket.h>
     35      0    stevel #include <sys/random.h>
     36   1676       jpk #include <sys/tsol/tndb.h>
     37   1676       jpk #include <sys/tsol/tnet.h>
     38      0    stevel 
     39      0    stevel #include <netinet/in.h>
     40      0    stevel #include <netinet/ip6.h>
     41      0    stevel #include <netinet/sctp.h>
     42      0    stevel 
     43      0    stevel #include <inet/common.h>
     44      0    stevel #include <inet/ip.h>
     45      0    stevel #include <inet/ip6.h>
     46      0    stevel #include <inet/ip_ire.h>
     47  11042      Erik #include <inet/ip_if.h>
     48  11042      Erik #include <inet/ip_ndp.h>
     49      0    stevel #include <inet/mib2.h>
     50      0    stevel #include <inet/nd.h>
     51      0    stevel #include <inet/optcom.h>
     52      0    stevel #include <inet/sctp_ip.h>
     53      0    stevel #include <inet/ipclassifier.h>
     54   1676       jpk 
     55      0    stevel #include "sctp_impl.h"
     56      0    stevel #include "sctp_addr.h"
     57   1932  vi117747 #include "sctp_asconf.h"
     58      0    stevel 
     59      0    stevel static struct kmem_cache *sctp_kmem_faddr_cache;
     60   1735    kcpoon static void sctp_init_faddr(sctp_t *, sctp_faddr_t *, in6_addr_t *, mblk_t *);
     61      0    stevel 
     62  11042      Erik /* Set the source address.  Refer to comments in sctp_get_dest(). */
     63   1932  vi117747 void
     64   1932  vi117747 sctp_set_saddr(sctp_t *sctp, sctp_faddr_t *fp)
     65      0    stevel {
     66   1719   jarrett 	boolean_t v6 = !fp->isv4;
     67   4818    kcpoon 	boolean_t addr_set;
     68   1719   jarrett 
     69   4818    kcpoon 	fp->saddr = sctp_get_valid_addr(sctp, v6, &addr_set);
     70   4818    kcpoon 	/*
     71   4818    kcpoon 	 * If there is no source address avaialble, mark this peer address
     72   4818    kcpoon 	 * as unreachable for now.  When the heartbeat timer fires, it will
     73  11042      Erik 	 * call sctp_get_dest() to re-check if there is any source address
     74   4818    kcpoon 	 * available.
     75   4818    kcpoon 	 */
     76   4818    kcpoon 	if (!addr_set)
     77   4818    kcpoon 		fp->state = SCTP_FADDRS_UNREACH;
     78      0    stevel }
     79      0    stevel 
     80      0    stevel /*
     81  11042      Erik  * Call this function to get information about a peer addr fp.
     82  11042      Erik  *
     83  11042      Erik  * Uses ip_attr_connect to avoid explicit use of ire and source address
     84  11042      Erik  * selection.
     85      0    stevel  */
     86      0    stevel void
     87  11042      Erik sctp_get_dest(sctp_t *sctp, sctp_faddr_t *fp)
     88      0    stevel {
     89   1735    kcpoon 	in6_addr_t	laddr;
     90  11042      Erik 	in6_addr_t	nexthop;
     91      0    stevel 	sctp_saddr_ipif_t *sp;
     92   1735    kcpoon 	int		hdrlen;
     93   3448  dh155122 	sctp_stack_t	*sctps = sctp->sctp_sctps;
     94  11042      Erik 	conn_t		*connp = sctp->sctp_connp;
     95  11042      Erik 	iulp_t		uinfo;
     96  11042      Erik 	uint_t		pmtu;
     97  11042      Erik 	int		error;
     98  11042      Erik 	uint32_t	flags = IPDF_VERIFY_DST | IPDF_IPSEC |
     99  11042      Erik 	    IPDF_SELECT_SRC | IPDF_UNIQUE_DCE;
    100      0    stevel 
    101  11042      Erik 	/*
    102  11042      Erik 	 * Tell sctp_make_mp it needs to call us again should we not
    103  11042      Erik 	 * complete and set the saddr.
    104  11042      Erik 	 */
    105  11042      Erik 	fp->saddr = ipv6_all_zeros;
    106      0    stevel 
    107      0    stevel 	/*
    108      0    stevel 	 * If this addr is not reachable, mark it as unconfirmed for now, the
    109      0    stevel 	 * state will be changed back to unreachable later in this function
    110      0    stevel 	 * if it is still the case.
    111      0    stevel 	 */
    112      0    stevel 	if (fp->state == SCTP_FADDRS_UNREACH) {
    113      0    stevel 		fp->state = SCTP_FADDRS_UNCONFIRMED;
    114      0    stevel 	}
    115      0    stevel 
    116  11042      Erik 	/*
    117  11042      Erik 	 * Socket is connected - enable PMTU discovery.
    118  11042      Erik 	 */
    119  11042      Erik 	if (!sctps->sctps_ignore_path_mtu)
    120  11042      Erik 		fp->ixa->ixa_flags |= IXAF_PMTU_DISCOVERY;
    121   1676       jpk 
    122  11042      Erik 	ip_attr_nexthop(&connp->conn_xmit_ipp, fp->ixa, &fp->faddr,
    123  11042      Erik 	    &nexthop);
    124      0    stevel 
    125  11042      Erik 	laddr = fp->saddr;
    126  11042      Erik 	error = ip_attr_connect(connp, fp->ixa, &laddr, &fp->faddr, &nexthop,
    127  11042      Erik 	    connp->conn_fport, &laddr, &uinfo, flags);
    128  11042      Erik 
    129  11042      Erik 	if (error != 0) {
    130  11042      Erik 		dprint(3, ("sctp_get_dest: no ire for %x:%x:%x:%x\n",
    131   1676       jpk 		    SCTP_PRINTADDR(fp->faddr)));
    132   1676       jpk 		/*
    133   1676       jpk 		 * It is tempting to just leave the src addr
    134   1676       jpk 		 * unspecified and let IP figure it out, but we
    135   1676       jpk 		 * *cannot* do this, since IP may choose a src addr
    136   1676       jpk 		 * that is not part of this association... unless
    137  11042      Erik 		 * this sctp has bound to all addrs.  So if the dest
    138   1676       jpk 		 * lookup fails, try to find one in our src addr
    139   1676       jpk 		 * list, unless the sctp has bound to all addrs, in
    140   1676       jpk 		 * which case we change the src addr to unspec.
    141   1676       jpk 		 *
    142   1676       jpk 		 * Note that if this is a v6 endpoint but it does
    143   1676       jpk 		 * not have any v4 address at this point (e.g. may
    144   1676       jpk 		 * have been  deleted), sctp_get_valid_addr() will
    145   1676       jpk 		 * return mapped INADDR_ANY.  In this case, this
    146   1676       jpk 		 * address should be marked not reachable so that
    147   1676       jpk 		 * it won't be used to send data.
    148   1676       jpk 		 */
    149   1932  vi117747 		sctp_set_saddr(sctp, fp);
    150   1735    kcpoon 		if (fp->state == SCTP_FADDRS_UNREACH)
    151   1735    kcpoon 			return;
    152   1735    kcpoon 		goto check_current;
    153   1676       jpk 	}
    154  11042      Erik 	ASSERT(fp->ixa->ixa_ire != NULL);
    155  11042      Erik 	ASSERT(!(fp->ixa->ixa_ire->ire_flags & (RTF_REJECT|RTF_BLACKHOLE)));
    156  11042      Erik 
    157  11042      Erik 	if (!sctp->sctp_loopback)
    158  11042      Erik 		sctp->sctp_loopback = uinfo.iulp_loopback;
    159      0    stevel 
    160   1735    kcpoon 	/* Make sure the laddr is part of this association */
    161  11042      Erik 	if ((sp = sctp_saddr_lookup(sctp, &laddr, 0)) != NULL &&
    162  11042      Erik 	    !sp->saddr_ipif_dontsrc) {
    163   1676       jpk 		if (sp->saddr_ipif_unconfirmed == 1)
    164   1676       jpk 			sp->saddr_ipif_unconfirmed = 0;
    165  11042      Erik 		/* We did IPsec policy lookup for laddr already */
    166   1676       jpk 		fp->saddr = laddr;
    167   1676       jpk 	} else {
    168  11042      Erik 		dprint(2, ("sctp_get_dest: src addr is not part of assoc "
    169  11042      Erik 		    "%x:%x:%x:%x\n", SCTP_PRINTADDR(laddr)));
    170   1735    kcpoon 
    171   1735    kcpoon 		/*
    172   1735    kcpoon 		 * Set the src to the first saddr and hope for the best.
    173  11042      Erik 		 * Note that this case should very seldomly
    174   1735    kcpoon 		 * happen.  One scenario this can happen is an app
    175   1735    kcpoon 		 * explicitly bind() to an address.  But that address is
    176   1735    kcpoon 		 * not the preferred source address to send to the peer.
    177   1735    kcpoon 		 */
    178   1932  vi117747 		sctp_set_saddr(sctp, fp);
    179   1735    kcpoon 		if (fp->state == SCTP_FADDRS_UNREACH) {
    180   1735    kcpoon 			return;
    181   1735    kcpoon 		}
    182      0    stevel 	}
    183      0    stevel 
    184   1735    kcpoon 	/*
    185      0    stevel 	 * Pull out RTO information for this faddr and use it if we don't
    186      0    stevel 	 * have any yet.
    187      0    stevel 	 */
    188  11042      Erik 	if (fp->srtt == -1 && uinfo.iulp_rtt != 0) {
    189    116    kcpoon 		/* The cached value is in ms. */
    190  11042      Erik 		fp->srtt = MSEC_TO_TICK(uinfo.iulp_rtt);
    191  11042      Erik 		fp->rttvar = MSEC_TO_TICK(uinfo.iulp_rtt_sd);
    192      0    stevel 		fp->rto = 3 * fp->srtt;
    193      0    stevel 
    194      0    stevel 		/* Bound the RTO by configured min and max values */
    195      0    stevel 		if (fp->rto < sctp->sctp_rto_min) {
    196      0    stevel 			fp->rto = sctp->sctp_rto_min;
    197      0    stevel 		}
    198      0    stevel 		if (fp->rto > sctp->sctp_rto_max) {
    199      0    stevel 			fp->rto = sctp->sctp_rto_max;
    200      0    stevel 		}
    201  10212    George 		SCTP_MAX_RTO(sctp, fp);
    202      0    stevel 	}
    203  11042      Erik 	pmtu = uinfo.iulp_mtu;
    204      0    stevel 
    205      0    stevel 	/*
    206      0    stevel 	 * Record the MTU for this faddr. If the MTU for this faddr has
    207      0    stevel 	 * changed, check if the assc MTU will also change.
    208      0    stevel 	 */
    209      0    stevel 	if (fp->isv4) {
    210      0    stevel 		hdrlen = sctp->sctp_hdr_len;
    211      0    stevel 	} else {
    212      0    stevel 		hdrlen = sctp->sctp_hdr6_len;
    213      0    stevel 	}
    214  11042      Erik 	if ((fp->sfa_pmss + hdrlen) != pmtu) {
    215      0    stevel 		/* Make sure that sfa_pmss is a multiple of SCTP_ALIGN. */
    216  11042      Erik 		fp->sfa_pmss = (pmtu - hdrlen) & ~(SCTP_ALIGN - 1);
    217      0    stevel 		if (fp->cwnd < (fp->sfa_pmss * 2)) {
    218   3795    kcpoon 			SET_CWND(fp, fp->sfa_pmss,
    219   3795    kcpoon 			    sctps->sctps_slow_start_initial);
    220      0    stevel 		}
    221      0    stevel 	}
    222      0    stevel 
    223   1735    kcpoon check_current:
    224   1735    kcpoon 	if (fp == sctp->sctp_current)
    225   1735    kcpoon 		sctp_set_faddr_current(sctp, fp);
    226      0    stevel }
    227      0    stevel 
    228      0    stevel void
    229  11042      Erik sctp_update_dce(sctp_t *sctp)
    230      0    stevel {
    231   1735    kcpoon 	sctp_faddr_t	*fp;
    232   3448  dh155122 	sctp_stack_t	*sctps = sctp->sctp_sctps;
    233  11042      Erik 	iulp_t		uinfo;
    234  11042      Erik 	ip_stack_t	*ipst = sctps->sctps_netstack->netstack_ip;
    235  11042      Erik 	uint_t		ifindex;
    236      0    stevel 
    237   1735    kcpoon 	for (fp = sctp->sctp_faddrs; fp != NULL; fp = fp->next) {
    238  11042      Erik 		bzero(&uinfo, sizeof (uinfo));
    239   1735    kcpoon 		/*
    240   1735    kcpoon 		 * Only record the PMTU for this faddr if we actually have
    241   1735    kcpoon 		 * done discovery. This prevents initialized default from
    242   1735    kcpoon 		 * clobbering any real info that IP may have.
    243   1735    kcpoon 		 */
    244   1735    kcpoon 		if (fp->pmtu_discovered) {
    245   1735    kcpoon 			if (fp->isv4) {
    246  11042      Erik 				uinfo.iulp_mtu = fp->sfa_pmss +
    247   1735    kcpoon 				    sctp->sctp_hdr_len;
    248   1735    kcpoon 			} else {
    249  11042      Erik 				uinfo.iulp_mtu = fp->sfa_pmss +
    250   1735    kcpoon 				    sctp->sctp_hdr6_len;
    251   1735    kcpoon 			}
    252   1735    kcpoon 		}
    253   3448  dh155122 		if (sctps->sctps_rtt_updates != 0 &&
    254   3448  dh155122 		    fp->rtt_updates >= sctps->sctps_rtt_updates) {
    255   1735    kcpoon 			/*
    256  11042      Erik 			 * dce_update_uinfo() merges these values with the
    257  11042      Erik 			 * old values.
    258   1735    kcpoon 			 */
    259  11042      Erik 			uinfo.iulp_rtt = TICK_TO_MSEC(fp->srtt);
    260  11042      Erik 			uinfo.iulp_rtt_sd = TICK_TO_MSEC(fp->rttvar);
    261   1735    kcpoon 			fp->rtt_updates = 0;
    262   1735    kcpoon 		}
    263  11042      Erik 		ifindex = 0;
    264  11042      Erik 		if (IN6_IS_ADDR_LINKSCOPE(&fp->faddr)) {
    265  11042      Erik 			/*
    266  11042      Erik 			 * If we are going to create a DCE we'd better have
    267  11042      Erik 			 * an ifindex
    268  11042      Erik 			 */
    269  11042      Erik 			if (fp->ixa->ixa_nce != NULL) {
    270  11042      Erik 				ifindex = fp->ixa->ixa_nce->nce_common->
    271  11042      Erik 				    ncec_ill->ill_phyint->phyint_ifindex;
    272  11042      Erik 			} else {
    273  11042      Erik 				continue;
    274  11042      Erik 			}
    275  11042      Erik 		}
    276  11042      Erik 
    277  11042      Erik 		(void) dce_update_uinfo(&fp->faddr, ifindex, &uinfo, ipst);
    278      0    stevel 	}
    279      0    stevel }
    280      0    stevel 
    281      0    stevel /*
    282  11042      Erik  * The sender must later set the total length in the IP header.
    283      0    stevel  */
    284      0    stevel mblk_t *
    285  11042      Erik sctp_make_mp(sctp_t *sctp, sctp_faddr_t *fp, int trailer)
    286      0    stevel {
    287      0    stevel 	mblk_t *mp;
    288      0    stevel 	size_t ipsctplen;
    289      0    stevel 	int isv4;
    290   3448  dh155122 	sctp_stack_t *sctps = sctp->sctp_sctps;
    291   4818    kcpoon 	boolean_t src_changed = B_FALSE;
    292      0    stevel 
    293  11042      Erik 	ASSERT(fp != NULL);
    294      0    stevel 	isv4 = fp->isv4;
    295      0    stevel 
    296  11042      Erik 	if (SCTP_IS_ADDR_UNSPEC(isv4, fp->saddr) ||
    297  11042      Erik 	    (fp->ixa->ixa_ire->ire_flags & (RTF_REJECT|RTF_BLACKHOLE))) {
    298  11042      Erik 		/* Need to pick a source */
    299  11042      Erik 		sctp_get_dest(sctp, fp);
    300   4818    kcpoon 		/*
    301   4818    kcpoon 		 * Although we still may not get an IRE, the source address
    302   4818    kcpoon 		 * may be changed in sctp_get_ire().  Set src_changed to
    303   4818    kcpoon 		 * true so that the source address is copied again.
    304   4818    kcpoon 		 */
    305   4818    kcpoon 		src_changed = B_TRUE;
    306   4818    kcpoon 	}
    307      0    stevel 
    308      0    stevel 	/* There is no suitable source address to use, return. */
    309      0    stevel 	if (fp->state == SCTP_FADDRS_UNREACH)
    310      0    stevel 		return (NULL);
    311  11042      Erik 
    312  11042      Erik 	ASSERT(fp->ixa->ixa_ire != NULL);
    313  11042      Erik 	ASSERT(!SCTP_IS_ADDR_UNSPEC(isv4, fp->saddr));
    314      0    stevel 
    315      0    stevel 	if (isv4) {
    316      0    stevel 		ipsctplen = sctp->sctp_hdr_len;
    317      0    stevel 	} else {
    318      0    stevel 		ipsctplen = sctp->sctp_hdr6_len;
    319      0    stevel 	}
    320      0    stevel 
    321  11042      Erik 	mp = allocb(ipsctplen + sctps->sctps_wroff_xtra + trailer, BPRI_MED);
    322      0    stevel 	if (mp == NULL) {
    323   1676       jpk 		ip1dbg(("sctp_make_mp: error making mp..\n"));
    324      0    stevel 		return (NULL);
    325      0    stevel 	}
    326   3448  dh155122 	mp->b_rptr += sctps->sctps_wroff_xtra;
    327      0    stevel 	mp->b_wptr = mp->b_rptr + ipsctplen;
    328      0    stevel 
    329      0    stevel 	ASSERT(OK_32PTR(mp->b_wptr));
    330      0    stevel 
    331      0    stevel 	if (isv4) {
    332      0    stevel 		ipha_t *iph = (ipha_t *)mp->b_rptr;
    333      0    stevel 
    334      0    stevel 		bcopy(sctp->sctp_iphc, mp->b_rptr, ipsctplen);
    335   4818    kcpoon 		if (fp != sctp->sctp_current || src_changed) {
    336   4818    kcpoon 			/* Fix the source and destination addresses. */
    337      0    stevel 			IN6_V4MAPPED_TO_IPADDR(&fp->faddr, iph->ipha_dst);
    338   4818    kcpoon 			IN6_V4MAPPED_TO_IPADDR(&fp->saddr, iph->ipha_src);
    339      0    stevel 		}
    340      0    stevel 		/* set or clear the don't fragment bit */
    341      0    stevel 		if (fp->df) {
    342      0    stevel 			iph->ipha_fragment_offset_and_flags = htons(IPH_DF);
    343      0    stevel 		} else {
    344      0    stevel 			iph->ipha_fragment_offset_and_flags = 0;
    345      0    stevel 		}
    346      0    stevel 	} else {
    347      0    stevel 		bcopy(sctp->sctp_iphc6, mp->b_rptr, ipsctplen);
    348   4818    kcpoon 		if (fp != sctp->sctp_current || src_changed) {
    349   4818    kcpoon 			/* Fix the source and destination addresses. */
    350      0    stevel 			((ip6_t *)(mp->b_rptr))->ip6_dst = fp->faddr;
    351   4818    kcpoon 			((ip6_t *)(mp->b_rptr))->ip6_src = fp->saddr;
    352      0    stevel 		}
    353      0    stevel 	}
    354      0    stevel 	ASSERT(sctp->sctp_connp != NULL);
    355      0    stevel 	return (mp);
    356      0    stevel }
    357      0    stevel 
    358      0    stevel /*
    359      0    stevel  * Notify upper layers about preferred write offset, write size.
    360      0    stevel  */
    361      0    stevel void
    362      0    stevel sctp_set_ulp_prop(sctp_t *sctp)
    363      0    stevel {
    364      0    stevel 	int hdrlen;
    365   8348      Eric 	struct sock_proto_props sopp;
    366   8348      Eric 
    367   3448  dh155122 	sctp_stack_t *sctps = sctp->sctp_sctps;
    368      0    stevel 
    369      0    stevel 	if (sctp->sctp_current->isv4) {
    370      0    stevel 		hdrlen = sctp->sctp_hdr_len;
    371      0    stevel 	} else {
    372      0    stevel 		hdrlen = sctp->sctp_hdr6_len;
    373      0    stevel 	}
    374      0    stevel 	ASSERT(sctp->sctp_ulpd);
    375      0    stevel 
    376  11042      Erik 	sctp->sctp_connp->conn_wroff = sctps->sctps_wroff_xtra + hdrlen +
    377  11042      Erik 	    sizeof (sctp_data_hdr_t);
    378  11042      Erik 
    379      0    stevel 	ASSERT(sctp->sctp_current->sfa_pmss == sctp->sctp_mss);
    380   8348      Eric 	bzero(&sopp, sizeof (sopp));
    381   8348      Eric 	sopp.sopp_flags = SOCKOPT_MAXBLK|SOCKOPT_WROFF;
    382  11042      Erik 	sopp.sopp_wroff = sctp->sctp_connp->conn_wroff;
    383   8348      Eric 	sopp.sopp_maxblk = sctp->sctp_mss - sizeof (sctp_data_hdr_t);
    384   8348      Eric 	sctp->sctp_ulp_prop(sctp->sctp_ulpd, &sopp);
    385      0    stevel }
    386      0    stevel 
    387  11042      Erik /*
    388  11042      Erik  * Set the lengths in the packet and the transmit attributes.
    389  11042      Erik  */
    390      0    stevel void
    391  11042      Erik sctp_set_iplen(sctp_t *sctp, mblk_t *mp, ip_xmit_attr_t *ixa)
    392      0    stevel {
    393      0    stevel 	uint16_t	sum = 0;
    394      0    stevel 	ipha_t		*iph;
    395      0    stevel 	ip6_t		*ip6h;
    396      0    stevel 	mblk_t		*pmp = mp;
    397      0    stevel 	boolean_t	isv4;
    398      0    stevel 
    399      0    stevel 	isv4 = (IPH_HDR_VERSION(mp->b_rptr) == IPV4_VERSION);
    400      0    stevel 	for (; pmp; pmp = pmp->b_cont)
    401      0    stevel 		sum += pmp->b_wptr - pmp->b_rptr;
    402      0    stevel 
    403  11042      Erik 	ixa->ixa_pktlen = sum;
    404      0    stevel 	if (isv4) {
    405      0    stevel 		iph = (ipha_t *)mp->b_rptr;
    406      0    stevel 		iph->ipha_length = htons(sum);
    407  11042      Erik 		ixa->ixa_ip_hdr_length = sctp->sctp_ip_hdr_len;
    408      0    stevel 	} else {
    409      0    stevel 		ip6h = (ip6_t *)mp->b_rptr;
    410  11042      Erik 		ip6h->ip6_plen = htons(sum - IPV6_HDR_LEN);
    411  11042      Erik 		ixa->ixa_ip_hdr_length = sctp->sctp_ip_hdr6_len;
    412      0    stevel 	}
    413      0    stevel }
    414      0    stevel 
    415      0    stevel int
    416      0    stevel sctp_compare_faddrsets(sctp_faddr_t *a1, sctp_faddr_t *a2)
    417      0    stevel {
    418      0    stevel 	int na1 = 0;
    419      0    stevel 	int overlap = 0;
    420      0    stevel 	int equal = 1;
    421      0    stevel 	int onematch;
    422      0    stevel 	sctp_faddr_t *fp1, *fp2;
    423      0    stevel 
    424      0    stevel 	for (fp1 = a1; fp1; fp1 = fp1->next) {
    425      0    stevel 		onematch = 0;
    426      0    stevel 		for (fp2 = a2; fp2; fp2 = fp2->next) {
    427      0    stevel 			if (IN6_ARE_ADDR_EQUAL(&fp1->faddr, &fp2->faddr)) {
    428      0    stevel 				overlap++;
    429      0    stevel 				onematch = 1;
    430      0    stevel 				break;
    431      0    stevel 			}
    432      0    stevel 			if (!onematch) {
    433      0    stevel 				equal = 0;
    434      0    stevel 			}
    435      0    stevel 		}
    436      0    stevel 		na1++;
    437      0    stevel 	}
    438      0    stevel 
    439      0    stevel 	if (equal) {
    440      0    stevel 		return (SCTP_ADDR_EQUAL);
    441      0    stevel 	}
    442      0    stevel 	if (overlap == na1) {
    443      0    stevel 		return (SCTP_ADDR_SUBSET);
    444      0    stevel 	}
    445      0    stevel 	if (overlap) {
    446      0    stevel 		return (SCTP_ADDR_OVERLAP);
    447      0    stevel 	}
    448      0    stevel 	return (SCTP_ADDR_DISJOINT);
    449      0    stevel }
    450      0    stevel 
    451      0    stevel /*
    452   9710       Ken  * Returns 0 on success, ENOMEM on memory allocation failure, EHOSTUNREACH
    453   9710       Ken  * if the connection credentials fail remote host accreditation or
    454   9710       Ken  * if the new destination does not support the previously established
    455   9710       Ken  * connection security label. If sleep is true, this function should
    456   9710       Ken  * never fail for a memory allocation failure. The boolean parameter
    457   9710       Ken  * "first" decides whether the newly created faddr structure should be
    458   1735    kcpoon  * added at the beginning of the list or at the end.
    459   1735    kcpoon  *
    460   1735    kcpoon  * Note: caller must hold conn fanout lock.
    461      0    stevel  */
    462   1735    kcpoon int
    463   1735    kcpoon sctp_add_faddr(sctp_t *sctp, in6_addr_t *addr, int sleep, boolean_t first)
    464      0    stevel {
    465   1735    kcpoon 	sctp_faddr_t	*faddr;
    466   1735    kcpoon 	mblk_t		*timer_mp;
    467   9710       Ken 	int		err;
    468  11042      Erik 	conn_t		*connp = sctp->sctp_connp;
    469      0    stevel 
    470   1676       jpk 	if (is_system_labeled()) {
    471  11042      Erik 		ip_xmit_attr_t	*ixa = connp->conn_ixa;
    472  11042      Erik 		ts_label_t	*effective_tsl = NULL;
    473  11042      Erik 
    474  11042      Erik 		ASSERT(ixa->ixa_tsl != NULL);
    475      0    stevel 
    476   9710       Ken 		/*
    477   9710       Ken 		 * Verify the destination is allowed to receive packets
    478   9710       Ken 		 * at the security label of the connection we are initiating.
    479   9710       Ken 		 *
    480  11042      Erik 		 * tsol_check_dest() will create a new effective label for
    481   9710       Ken 		 * this connection with a modified label or label flags only
    482  11042      Erik 		 * if there are changes from the original label.
    483   9710       Ken 		 *
    484   9710       Ken 		 * Accept whatever label we get if this is the first
    485   9710       Ken 		 * destination address for this connection. The security
    486   9710       Ken 		 * label and label flags must match any previuous settings
    487   9710       Ken 		 * for all subsequent destination addresses.
    488   9710       Ken 		 */
    489   9710       Ken 		if (IN6_IS_ADDR_V4MAPPED(addr)) {
    490   9710       Ken 			uint32_t dst;
    491   9710       Ken 			IN6_V4MAPPED_TO_IPADDR(addr, dst);
    492  11042      Erik 			err = tsol_check_dest(ixa->ixa_tsl,
    493  11042      Erik 			    &dst, IPV4_VERSION, connp->conn_mac_mode,
    494  11042      Erik 			    connp->conn_zone_is_global, &effective_tsl);
    495   9710       Ken 		} else {
    496  11042      Erik 			err = tsol_check_dest(ixa->ixa_tsl,
    497  11042      Erik 			    addr, IPV6_VERSION, connp->conn_mac_mode,
    498  11042      Erik 			    connp->conn_zone_is_global, &effective_tsl);
    499   1676       jpk 		}
    500   9710       Ken 		if (err != 0)
    501   9710       Ken 			return (err);
    502  11042      Erik 
    503  11042      Erik 		if (sctp->sctp_faddrs == NULL && effective_tsl != NULL) {
    504  11042      Erik 			ip_xmit_attr_replace_tsl(ixa, effective_tsl);
    505  11042      Erik 		} else if (effective_tsl != NULL) {
    506  11042      Erik 			label_rele(effective_tsl);
    507   9710       Ken 			return (EHOSTUNREACH);
    508   9710       Ken 		}
    509      0    stevel 	}
    510   1676       jpk 
    511   1676       jpk 	if ((faddr = kmem_cache_alloc(sctp_kmem_faddr_cache, sleep)) == NULL)
    512   1676       jpk 		return (ENOMEM);
    513  11042      Erik 	bzero(faddr, sizeof (*faddr));
    514   4691    kcpoon 	timer_mp = sctp_timer_alloc((sctp), sctp_rexmit_timer, sleep);
    515   1735    kcpoon 	if (timer_mp == NULL) {
    516   1735    kcpoon 		kmem_cache_free(sctp_kmem_faddr_cache, faddr);
    517   1735    kcpoon 		return (ENOMEM);
    518   1735    kcpoon 	}
    519   1735    kcpoon 	((sctpt_t *)(timer_mp->b_rptr))->sctpt_faddr = faddr;
    520      0    stevel 
    521  11042      Erik 	/* Start with any options set on the conn */
    522  11042      Erik 	faddr->ixa = conn_get_ixa_exclusive(connp);
    523  11042      Erik 	if (faddr->ixa == NULL) {
    524  11042      Erik 		freemsg(timer_mp);
    525  11042      Erik 		kmem_cache_free(sctp_kmem_faddr_cache, faddr);
    526  11042      Erik 		return (ENOMEM);
    527  11042      Erik 	}
    528  11042      Erik 	faddr->ixa->ixa_notify_cookie = connp->conn_sctp;
    529  11042      Erik 
    530   1735    kcpoon 	sctp_init_faddr(sctp, faddr, addr, timer_mp);
    531  11042      Erik 	ASSERT(faddr->ixa->ixa_cred != NULL);
    532   4818    kcpoon 
    533  11042      Erik 	/* ip_attr_connect didn't allow broadcats/multicast dest */
    534      0    stevel 	ASSERT(faddr->next == NULL);
    535      0    stevel 
    536   1676       jpk 	if (sctp->sctp_faddrs == NULL) {
    537   1676       jpk 		ASSERT(sctp->sctp_lastfaddr == NULL);
    538   1676       jpk 		/* only element on list; first and last are same */
    539   1676       jpk 		sctp->sctp_faddrs = sctp->sctp_lastfaddr = faddr;
    540   1676       jpk 	} else if (first) {
    541   1676       jpk 		ASSERT(sctp->sctp_lastfaddr != NULL);
    542   1676       jpk 		faddr->next = sctp->sctp_faddrs;
    543   1676       jpk 		sctp->sctp_faddrs = faddr;
    544   1676       jpk 	} else {
    545      0    stevel 		sctp->sctp_lastfaddr->next = faddr;
    546   1676       jpk 		sctp->sctp_lastfaddr = faddr;
    547      0    stevel 	}
    548    852  vi117747 	sctp->sctp_nfaddrs++;
    549      0    stevel 
    550      0    stevel 	return (0);
    551      0    stevel }
    552      0    stevel 
    553      0    stevel sctp_faddr_t *
    554      0    stevel sctp_lookup_faddr(sctp_t *sctp, in6_addr_t *addr)
    555      0    stevel {
    556      0    stevel 	sctp_faddr_t *fp;
    557      0    stevel 
    558      0    stevel 	for (fp = sctp->sctp_faddrs; fp != NULL; fp = fp->next) {
    559      0    stevel 		if (IN6_ARE_ADDR_EQUAL(&fp->faddr, addr))
    560      0    stevel 			break;
    561      0    stevel 	}
    562      0    stevel 
    563      0    stevel 	return (fp);
    564      0    stevel }
    565      0    stevel 
    566      0    stevel sctp_faddr_t *
    567      0    stevel sctp_lookup_faddr_nosctp(sctp_faddr_t *fp, in6_addr_t *addr)
    568      0    stevel {
    569      0    stevel 	for (; fp; fp = fp->next) {
    570      0    stevel 		if (IN6_ARE_ADDR_EQUAL(&fp->faddr, addr)) {
    571      0    stevel 			break;
    572      0    stevel 		}
    573      0    stevel 	}
    574      0    stevel 
    575      0    stevel 	return (fp);
    576      0    stevel }
    577      0    stevel 
    578   1735    kcpoon /*
    579   1735    kcpoon  * To change the currently used peer address to the specified one.
    580   1735    kcpoon  */
    581      0    stevel void
    582   1735    kcpoon sctp_set_faddr_current(sctp_t *sctp, sctp_faddr_t *fp)
    583      0    stevel {
    584   1735    kcpoon 	/* Now setup the composite header. */
    585      0    stevel 	if (fp->isv4) {
    586      0    stevel 		IN6_V4MAPPED_TO_IPADDR(&fp->faddr,
    587      0    stevel 		    sctp->sctp_ipha->ipha_dst);
    588      0    stevel 		IN6_V4MAPPED_TO_IPADDR(&fp->saddr, sctp->sctp_ipha->ipha_src);
    589      0    stevel 		/* update don't fragment bit */
    590      0    stevel 		if (fp->df) {
    591      0    stevel 			sctp->sctp_ipha->ipha_fragment_offset_and_flags =
    592      0    stevel 			    htons(IPH_DF);
    593      0    stevel 		} else {
    594      0    stevel 			sctp->sctp_ipha->ipha_fragment_offset_and_flags = 0;
    595      0    stevel 		}
    596      0    stevel 	} else {
    597      0    stevel 		sctp->sctp_ip6h->ip6_dst = fp->faddr;
    598      0    stevel 		sctp->sctp_ip6h->ip6_src = fp->saddr;
    599      0    stevel 	}
    600   1735    kcpoon 
    601   1735    kcpoon 	sctp->sctp_current = fp;
    602   1735    kcpoon 	sctp->sctp_mss = fp->sfa_pmss;
    603   1735    kcpoon 
    604   1735    kcpoon 	/* Update the uppper layer for the change. */
    605   1735    kcpoon 	if (!SCTP_IS_DETACHED(sctp))
    606   1735    kcpoon 		sctp_set_ulp_prop(sctp);
    607      0    stevel }
    608      0    stevel 
    609      0    stevel void
    610      0    stevel sctp_redo_faddr_srcs(sctp_t *sctp)
    611      0    stevel {
    612      0    stevel 	sctp_faddr_t *fp;
    613      0    stevel 
    614      0    stevel 	for (fp = sctp->sctp_faddrs; fp != NULL; fp = fp->next) {
    615  11042      Erik 		sctp_get_dest(sctp, fp);
    616      0    stevel 	}
    617      0    stevel }
    618      0    stevel 
    619      0    stevel void
    620      0    stevel sctp_faddr_alive(sctp_t *sctp, sctp_faddr_t *fp)
    621      0    stevel {
    622  11066    rafael 	int64_t now = ddi_get_lbolt64();
    623      0    stevel 
    624      0    stevel 	fp->strikes = 0;
    625      0    stevel 	sctp->sctp_strikes = 0;
    626      0    stevel 	fp->lastactive = now;
    627      0    stevel 	fp->hb_expiry = now + SET_HB_INTVL(fp);
    628      0    stevel 	fp->hb_pending = B_FALSE;
    629      0    stevel 	if (fp->state != SCTP_FADDRS_ALIVE) {
    630      0    stevel 		fp->state = SCTP_FADDRS_ALIVE;
    631      0    stevel 		sctp_intf_event(sctp, fp->faddr, SCTP_ADDR_AVAILABLE, 0);
    632   4818    kcpoon 		/* Should have a full IRE now */
    633  11042      Erik 		sctp_get_dest(sctp, fp);
    634      0    stevel 
    635   1735    kcpoon 		/*
    636   1735    kcpoon 		 * If this is the primary, switch back to it now.  And
    637   1735    kcpoon 		 * we probably want to reset the source addr used to reach
    638   1735    kcpoon 		 * it.
    639  11042      Erik 		 * Note that if we didn't find a source in sctp_get_dest
    640  11042      Erik 		 * then we'd be unreachable at this point in time.
    641   1735    kcpoon 		 */
    642  11042      Erik 		if (fp == sctp->sctp_primary &&
    643  11042      Erik 		    fp->state != SCTP_FADDRS_UNREACH) {
    644   1735    kcpoon 			sctp_set_faddr_current(sctp, fp);
    645   1735    kcpoon 			return;
    646      0    stevel 		}
    647      0    stevel 	}
    648      0    stevel }
    649      0    stevel 
    650      0    stevel int
    651      0    stevel sctp_is_a_faddr_clean(sctp_t *sctp)
    652      0    stevel {
    653      0    stevel 	sctp_faddr_t *fp;
    654      0    stevel 
    655      0    stevel 	for (fp = sctp->sctp_faddrs; fp; fp = fp->next) {
    656      0    stevel 		if (fp->state == SCTP_FADDRS_ALIVE && fp->strikes == 0) {
    657      0    stevel 			return (1);
    658      0    stevel 		}
    659      0    stevel 	}
    660      0    stevel 
    661      0    stevel 	return (0);
    662      0    stevel }
    663      0    stevel 
    664      0    stevel /*
    665      0    stevel  * Returns 0 if there is at leave one other active faddr, -1 if there
    666      0    stevel  * are none. If there are none left, faddr_dead() will start killing the
    667      0    stevel  * association.
    668      0    stevel  * If the downed faddr was the current faddr, a new current faddr
    669      0    stevel  * will be chosen.
    670      0    stevel  */
    671      0    stevel int
    672      0    stevel sctp_faddr_dead(sctp_t *sctp, sctp_faddr_t *fp, int newstate)
    673      0    stevel {
    674      0    stevel 	sctp_faddr_t *ofp;
    675   3448  dh155122 	sctp_stack_t *sctps = sctp->sctp_sctps;
    676      0    stevel 
    677      0    stevel 	if (fp->state == SCTP_FADDRS_ALIVE) {
    678      0    stevel 		sctp_intf_event(sctp, fp->faddr, SCTP_ADDR_UNREACHABLE, 0);
    679      0    stevel 	}
    680      0    stevel 	fp->state = newstate;
    681      0    stevel 
    682      0    stevel 	dprint(1, ("sctp_faddr_dead: %x:%x:%x:%x down (state=%d)\n",
    683      0    stevel 	    SCTP_PRINTADDR(fp->faddr), newstate));
    684      0    stevel 
    685      0    stevel 	if (fp == sctp->sctp_current) {
    686      0    stevel 		/* Current faddr down; need to switch it */
    687      0    stevel 		sctp->sctp_current = NULL;
    688      0    stevel 	}
    689      0    stevel 
    690      0    stevel 	/* Find next alive faddr */
    691      0    stevel 	ofp = fp;
    692   1735    kcpoon 	for (fp = fp->next; fp != NULL; fp = fp->next) {
    693      0    stevel 		if (fp->state == SCTP_FADDRS_ALIVE) {
    694      0    stevel 			break;
    695      0    stevel 		}
    696      0    stevel 	}
    697      0    stevel 
    698      0    stevel 	if (fp == NULL) {
    699      0    stevel 		/* Continue from beginning of list */
    700      0    stevel 		for (fp = sctp->sctp_faddrs; fp != ofp; fp = fp->next) {
    701      0    stevel 			if (fp->state == SCTP_FADDRS_ALIVE) {
    702      0    stevel 				break;
    703      0    stevel 			}
    704      0    stevel 		}
    705      0    stevel 	}
    706      0    stevel 
    707   1735    kcpoon 	/*
    708   1735    kcpoon 	 * Find a new fp, so if the current faddr is dead, use the new fp
    709   1735    kcpoon 	 * as the current one.
    710   1735    kcpoon 	 */
    711      0    stevel 	if (fp != ofp) {
    712      0    stevel 		if (sctp->sctp_current == NULL) {
    713      0    stevel 			dprint(1, ("sctp_faddr_dead: failover->%x:%x:%x:%x\n",
    714      0    stevel 			    SCTP_PRINTADDR(fp->faddr)));
    715   1735    kcpoon 			/*
    716   1735    kcpoon 			 * Note that we don't need to reset the source addr
    717   1735    kcpoon 			 * of the new fp.
    718   1735    kcpoon 			 */
    719   1735    kcpoon 			sctp_set_faddr_current(sctp, fp);
    720      0    stevel 		}
    721      0    stevel 		return (0);
    722      0    stevel 	}
    723      0    stevel 
    724      0    stevel 
    725      0    stevel 	/* All faddrs are down; kill the association */
    726      0    stevel 	dprint(1, ("sctp_faddr_dead: all faddrs down, killing assoc\n"));
    727   3448  dh155122 	BUMP_MIB(&sctps->sctps_mib, sctpAborted);
    728      0    stevel 	sctp_assoc_event(sctp, sctp->sctp_state < SCTPS_ESTABLISHED ?
    729      0    stevel 	    SCTP_CANT_STR_ASSOC : SCTP_COMM_LOST, 0, NULL);
    730      0    stevel 	sctp_clean_death(sctp, sctp->sctp_client_errno ?
    731      0    stevel 	    sctp->sctp_client_errno : ETIMEDOUT);
    732      0    stevel 
    733      0    stevel 	return (-1);
    734      0    stevel }
    735      0    stevel 
    736      0    stevel sctp_faddr_t *
    737      0    stevel sctp_rotate_faddr(sctp_t *sctp, sctp_faddr_t *ofp)
    738      0    stevel {
    739      0    stevel 	sctp_faddr_t *nfp = NULL;
    740      0    stevel 
    741      0    stevel 	if (ofp == NULL) {
    742      0    stevel 		ofp = sctp->sctp_current;
    743      0    stevel 	}
    744      0    stevel 
    745      0    stevel 	/* Find the next live one */
    746      0    stevel 	for (nfp = ofp->next; nfp != NULL; nfp = nfp->next) {
    747      0    stevel 		if (nfp->state == SCTP_FADDRS_ALIVE) {
    748      0    stevel 			break;
    749      0    stevel 		}
    750      0    stevel 	}
    751      0    stevel 
    752      0    stevel 	if (nfp == NULL) {
    753      0    stevel 		/* Continue from beginning of list */
    754      0    stevel 		for (nfp = sctp->sctp_faddrs; nfp != ofp; nfp = nfp->next) {
    755      0    stevel 			if (nfp->state == SCTP_FADDRS_ALIVE) {
    756      0    stevel 				break;
    757      0    stevel 			}
    758      0    stevel 		}
    759      0    stevel 	}
    760      0    stevel 
    761      0    stevel 	/*
    762      0    stevel 	 * nfp could only be NULL if all faddrs are down, and when
    763      0    stevel 	 * this happens, faddr_dead() should have killed the
    764      0    stevel 	 * association. Hence this assertion...
    765      0    stevel 	 */
    766      0    stevel 	ASSERT(nfp != NULL);
    767      0    stevel 	return (nfp);
    768      0    stevel }
    769      0    stevel 
    770      0    stevel void
    771      0    stevel sctp_unlink_faddr(sctp_t *sctp, sctp_faddr_t *fp)
    772      0    stevel {
    773      0    stevel 	sctp_faddr_t *fpp;
    774      0    stevel 
    775      0    stevel 	if (!sctp->sctp_faddrs) {
    776      0    stevel 		return;
    777      0    stevel 	}
    778      0    stevel 
    779      0    stevel 	if (fp->timer_mp != NULL) {
    780      0    stevel 		sctp_timer_free(fp->timer_mp);
    781      0    stevel 		fp->timer_mp = NULL;
    782      0    stevel 		fp->timer_running = 0;
    783      0    stevel 	}
    784      0    stevel 	if (fp->rc_timer_mp != NULL) {
    785      0    stevel 		sctp_timer_free(fp->rc_timer_mp);
    786      0    stevel 		fp->rc_timer_mp = NULL;
    787      0    stevel 		fp->rc_timer_running = 0;
    788      0    stevel 	}
    789  11042      Erik 	if (fp->ixa != NULL) {
    790  11042      Erik 		ixa_refrele(fp->ixa);
    791  11042      Erik 		fp->ixa = NULL;
    792      0    stevel 	}
    793      0    stevel 
    794      0    stevel 	if (fp == sctp->sctp_faddrs) {
    795      0    stevel 		goto gotit;
    796      0    stevel 	}
    797      0    stevel 
    798      0    stevel 	for (fpp = sctp->sctp_faddrs; fpp->next != fp; fpp = fpp->next)
    799      0    stevel 		;
    800      0    stevel 
    801      0    stevel gotit:
    802      0    stevel 	ASSERT(sctp->sctp_conn_tfp != NULL);
    803      0    stevel 	mutex_enter(&sctp->sctp_conn_tfp->tf_lock);
    804      0    stevel 	if (fp == sctp->sctp_faddrs) {
    805      0    stevel 		sctp->sctp_faddrs = fp->next;
    806      0    stevel 	} else {
    807      0    stevel 		fpp->next = fp->next;
    808      0    stevel 	}
    809      0    stevel 	mutex_exit(&sctp->sctp_conn_tfp->tf_lock);
    810      0    stevel 	kmem_cache_free(sctp_kmem_faddr_cache, fp);
    811    852  vi117747 	sctp->sctp_nfaddrs--;
    812      0    stevel }
    813      0    stevel 
    814      0    stevel void
    815      0    stevel sctp_zap_faddrs(sctp_t *sctp, int caller_holds_lock)
    816      0    stevel {
    817      0    stevel 	sctp_faddr_t *fp, *fpn;
    818      0    stevel 
    819      0    stevel 	if (sctp->sctp_faddrs == NULL) {
    820      0    stevel 		ASSERT(sctp->sctp_lastfaddr == NULL);
    821      0    stevel 		return;
    822      0    stevel 	}
    823      0    stevel 
    824      0    stevel 	ASSERT(sctp->sctp_lastfaddr != NULL);
    825      0    stevel 	sctp->sctp_lastfaddr = NULL;
    826      0    stevel 	sctp->sctp_current = NULL;
    827      0    stevel 	sctp->sctp_primary = NULL;
    828      0    stevel 
    829      0    stevel 	sctp_free_faddr_timers(sctp);
    830      0    stevel 
    831      0    stevel 	if (sctp->sctp_conn_tfp != NULL && !caller_holds_lock) {
    832      0    stevel 		/* in conn fanout; need to hold lock */
    833      0    stevel 		mutex_enter(&sctp->sctp_conn_tfp->tf_lock);
    834      0    stevel 	}
    835      0    stevel 
    836      0    stevel 	for (fp = sctp->sctp_faddrs; fp; fp = fpn) {
    837      0    stevel 		fpn = fp->next;
    838  11042      Erik 		if (fp->ixa != NULL) {
    839  11042      Erik 			ixa_refrele(fp->ixa);
    840  11042      Erik 			fp->ixa = NULL;
    841  11042      Erik 		}
    842      0    stevel 		kmem_cache_free(sctp_kmem_faddr_cache, fp);
    843    852  vi117747 		sctp->sctp_nfaddrs--;
    844      0    stevel 	}
    845      0    stevel 
    846      0    stevel 	sctp->sctp_faddrs = NULL;
    847    852  vi117747 	ASSERT(sctp->sctp_nfaddrs == 0);
    848      0    stevel 	if (sctp->sctp_conn_tfp != NULL && !caller_holds_lock) {
    849      0    stevel 		mutex_exit(&sctp->sctp_conn_tfp->tf_lock);
    850      0    stevel 	}
    851      0    stevel 
    852      0    stevel }
    853      0    stevel 
    854      0    stevel void
    855      0    stevel sctp_zap_addrs(sctp_t *sctp)
    856      0    stevel {
    857      0    stevel 	sctp_zap_faddrs(sctp, 0);
    858      0    stevel 	sctp_free_saddrs(sctp);
    859      0    stevel }
    860      0    stevel 
    861      0    stevel /*
    862  11042      Erik  * Build two SCTP header templates; one for IPv4 and one for IPv6.
    863  11042      Erik  * Store them in sctp_iphc and sctp_iphc6 respectively (and related fields).
    864  11042      Erik  * There are no IP addresses in the templates, but the port numbers and
    865  11042      Erik  * verifier are field in from the conn_t and sctp_t.
    866  11042      Erik  *
    867  11042      Erik  * Returns failure if can't allocate memory, or if there is a problem
    868  11042      Erik  * with a routing header/option.
    869  11042      Erik  *
    870  11042      Erik  * We allocate space for the minimum sctp header (sctp_hdr_t).
    871  11042      Erik  *
    872  11042      Erik  * We massage an routing option/header. There is no checksum implication
    873  11042      Erik  * for a routing header for sctp.
    874  11042      Erik  *
    875  11042      Erik  * Caller needs to update conn_wroff if desired.
    876  11042      Erik  *
    877  11042      Erik  * TSol notes: This assumes that a SCTP association has a single peer label
    878  11042      Erik  * since we only track a single pair of ipp_label_v4/v6 and not a separate one
    879  11042      Erik  * for each faddr.
    880      0    stevel  */
    881      0    stevel int
    882  11042      Erik sctp_build_hdrs(sctp_t *sctp, int sleep)
    883      0    stevel {
    884  11042      Erik 	conn_t		*connp = sctp->sctp_connp;
    885  11042      Erik 	ip_pkt_t	*ipp = &connp->conn_xmit_ipp;
    886  11042      Erik 	uint_t		ip_hdr_length;
    887  11042      Erik 	uchar_t		*hdrs;
    888  11042      Erik 	uint_t		hdrs_len;
    889  11042      Erik 	uint_t		ulp_hdr_length = sizeof (sctp_hdr_t);
    890  11042      Erik 	ipha_t		*ipha;
    891  11042      Erik 	ip6_t		*ip6h;
    892      0    stevel 	sctp_hdr_t	*sctph;
    893  11042      Erik 	in6_addr_t	v6src, v6dst;
    894  11042      Erik 	ipaddr_t	v4src, v4dst;
    895      0    stevel 
    896  11042      Erik 	v4src = connp->conn_saddr_v4;
    897  11042      Erik 	v4dst = connp->conn_faddr_v4;
    898  11042      Erik 	v6src = connp->conn_saddr_v6;
    899  11042      Erik 	v6dst = connp->conn_faddr_v6;
    900  11042      Erik 
    901  11042      Erik 	/* First do IPv4 header */
    902  11042      Erik 	ip_hdr_length = ip_total_hdrs_len_v4(ipp);
    903  11042      Erik 
    904  11042      Erik 	/* In case of TX label and IP options it can be too much */
    905  11042      Erik 	if (ip_hdr_length > IP_MAX_HDR_LENGTH) {
    906  11042      Erik 		/* Preserves existing TX errno for this */
    907  11042      Erik 		return (EHOSTUNREACH);
    908      0    stevel 	}
    909  11042      Erik 	hdrs_len = ip_hdr_length + ulp_hdr_length;
    910  11042      Erik 	ASSERT(hdrs_len != 0);
    911      0    stevel 
    912  11042      Erik 	if (hdrs_len != sctp->sctp_iphc_len) {
    913  11042      Erik 		/* Allocate new before we free any old */
    914  11042      Erik 		hdrs = kmem_alloc(hdrs_len, sleep);
    915      0    stevel 		if (hdrs == NULL)
    916      0    stevel 			return (ENOMEM);
    917      0    stevel 
    918  11042      Erik 		if (sctp->sctp_iphc != NULL)
    919  11042      Erik 			kmem_free(sctp->sctp_iphc, sctp->sctp_iphc_len);
    920  11042      Erik 		sctp->sctp_iphc = hdrs;
    921  11042      Erik 		sctp->sctp_iphc_len = hdrs_len;
    922  11042      Erik 	} else {
    923  11042      Erik 		hdrs = sctp->sctp_iphc;
    924  11042      Erik 	}
    925  11042      Erik 	sctp->sctp_hdr_len = sctp->sctp_iphc_len;
    926  11042      Erik 	sctp->sctp_ip_hdr_len = ip_hdr_length;
    927  11042      Erik 
    928  11042      Erik 	sctph = (sctp_hdr_t *)(hdrs + ip_hdr_length);
    929  11042      Erik 	sctp->sctp_sctph = sctph;
    930  11042      Erik 	sctph->sh_sport = connp->conn_lport;
    931  11042      Erik 	sctph->sh_dport = connp->conn_fport;
    932  11042      Erik 	sctph->sh_verf = sctp->sctp_fvtag;
    933  11042      Erik 	sctph->sh_chksum = 0;
    934  11042      Erik 
    935  11042      Erik 	ipha = (ipha_t *)hdrs;
    936  11042      Erik 	sctp->sctp_ipha = ipha;
    937  11042      Erik 
    938  11042      Erik 	ipha->ipha_src = v4src;
    939  11042      Erik 	ipha->ipha_dst = v4dst;
    940  11042      Erik 	ip_build_hdrs_v4(hdrs, ip_hdr_length, ipp, connp->conn_proto);
    941  11042      Erik 	ipha->ipha_length = htons(hdrs_len);
    942  11042      Erik 	ipha->ipha_fragment_offset_and_flags = 0;
    943  11042      Erik 
    944  11042      Erik 	if (ipp->ipp_fields & IPPF_IPV4_OPTIONS)
    945  11042      Erik 		(void) ip_massage_options(ipha, connp->conn_netstack);
    946  11042      Erik 
    947  11042      Erik 	/* Now IPv6 */
    948  11042      Erik 	ip_hdr_length = ip_total_hdrs_len_v6(ipp);
    949  11042      Erik 	hdrs_len = ip_hdr_length + ulp_hdr_length;
    950  11042      Erik 	ASSERT(hdrs_len != 0);
    951  11042      Erik 
    952  11042      Erik 	if (hdrs_len != sctp->sctp_iphc6_len) {
    953  11042      Erik 		/* Allocate new before we free any old */
    954  11042      Erik 		hdrs = kmem_alloc(hdrs_len, sleep);
    955  11042      Erik 		if (hdrs == NULL)
    956  11042      Erik 			return (ENOMEM);
    957  11042      Erik 
    958  11042      Erik 		if (sctp->sctp_iphc6 != NULL)
    959      0    stevel 			kmem_free(sctp->sctp_iphc6, sctp->sctp_iphc6_len);
    960      0    stevel 		sctp->sctp_iphc6 = hdrs;
    961      0    stevel 		sctp->sctp_iphc6_len = hdrs_len;
    962  11042      Erik 	} else {
    963  11042      Erik 		hdrs = sctp->sctp_iphc6;
    964      0    stevel 	}
    965  11042      Erik 	sctp->sctp_hdr6_len = sctp->sctp_iphc6_len;
    966  11042      Erik 	sctp->sctp_ip_hdr6_len = ip_hdr_length;
    967      0    stevel 
    968  11042      Erik 	sctph = (sctp_hdr_t *)(hdrs + ip_hdr_length);
    969  11042      Erik 	sctp->sctp_sctph6 = sctph;
    970  11042      Erik 	sctph->sh_sport = connp->conn_lport;
    971  11042      Erik 	sctph->sh_dport = connp->conn_fport;
    972  11042      Erik 	sctph->sh_verf = sctp->sctp_fvtag;
    973  11042      Erik 	sctph->sh_chksum = 0;
    974      0    stevel 
    975  11042      Erik 	ip6h = (ip6_t *)hdrs;
    976  11042      Erik 	sctp->sctp_ip6h = ip6h;
    977      0    stevel 
    978  11042      Erik 	ip6h->ip6_src = v6src;
    979  11042      Erik 	ip6h->ip6_dst = v6dst;
    980  11042      Erik 	ip_build_hdrs_v6(hdrs, ip_hdr_length, ipp, connp->conn_proto,
    981  11042      Erik 	    connp->conn_flowinfo);
    982  11042      Erik 	ip6h->ip6_plen = htons(hdrs_len - IPV6_HDR_LEN);
    983      0    stevel 
    984  11042      Erik 	if (ipp->ipp_fields & IPPF_RTHDR) {
    985  11042      Erik 		uint8_t		*end;
    986  11042      Erik 		ip6_rthdr_t	*rth;
    987      0    stevel 
    988  11042      Erik 		end = (uint8_t *)ip6h + ip_hdr_length;
    989  11042      Erik 		rth = ip_find_rthdr_v6(ip6h, end);
    990   3448  dh155122 		if (rth != NULL) {
    991  11042      Erik 			(void) ip_massage_options_v6(ip6h, rth,
    992  11042      Erik 			    connp->conn_netstack);
    993   3448  dh155122 		}
    994      0    stevel 
    995  11042      Erik 		/*
    996  11042      Erik 		 * Verify that the first hop isn't a mapped address.
    997  11042      Erik 		 * Routers along the path need to do this verification
    998  11042      Erik 		 * for subsequent hops.
    999  11042      Erik 		 */
   1000  11042      Erik 		if (IN6_IS_ADDR_V4MAPPED(&ip6h->ip6_dst))
   1001  11042      Erik 			return (EADDRNOTAVAIL);
   1002   1676       jpk 	}
   1003   1676       jpk 	return (0);
   1004   1676       jpk }
   1005   1676       jpk 
   1006   1676       jpk static int
   1007  11042      Erik sctp_v4_label(sctp_t *sctp, sctp_faddr_t *fp)
   1008   1676       jpk {
   1009  11042      Erik 	conn_t *connp = sctp->sctp_connp;
   1010   1676       jpk 
   1011  11042      Erik 	ASSERT(fp->ixa->ixa_flags & IXAF_IS_IPV4);
   1012  11042      Erik 	return (conn_update_label(connp, fp->ixa, &fp->faddr,
   1013  11042      Erik 	    &connp->conn_xmit_ipp));
   1014  11042      Erik }
   1015  11042      Erik 
   1016  11042      Erik static int
   1017  11042      Erik sctp_v6_label(sctp_t *sctp, sctp_faddr_t *fp)
   1018  11042      Erik {
   1019  11042      Erik 	conn_t *connp = sctp->sctp_connp;
   1020  11042      Erik 
   1021  11042      Erik 	ASSERT(!(fp->ixa->ixa_flags & IXAF_IS_IPV4));
   1022  11042      Erik 	return (conn_update_label(connp, fp->ixa, &fp->faddr,
   1023  11042      Erik 	    &connp->conn_xmit_ipp));
   1024   1676       jpk }
   1025   1676       jpk 
   1026      0    stevel /*
   1027      0    stevel  * XXX implement more sophisticated logic
   1028  11042      Erik  *
   1029  11042      Erik  * Tsol note: We have already verified the addresses using tsol_check_dest
   1030  11042      Erik  * in sctp_add_faddr, thus no need to redo that here.
   1031  11042      Erik  * We do setup ipp_label_v4 and ipp_label_v6 based on which addresses
   1032  11042      Erik  * we have.
   1033      0    stevel  */
   1034   1676       jpk int
   1035   1735    kcpoon sctp_set_hdraddrs(sctp_t *sctp)
   1036      0    stevel {
   1037      0    stevel 	sctp_faddr_t *fp;
   1038      0    stevel 	int gotv4 = 0;
   1039      0    stevel 	int gotv6 = 0;
   1040  11042      Erik 	conn_t *connp = sctp->sctp_connp;
   1041      0    stevel 
   1042      0    stevel 	ASSERT(sctp->sctp_faddrs != NULL);
   1043      0    stevel 	ASSERT(sctp->sctp_nsaddrs > 0);
   1044      0    stevel 
   1045      0    stevel 	/* Set up using the primary first */
   1046  11042      Erik 	connp->conn_faddr_v6 = sctp->sctp_primary->faddr;
   1047  11042      Erik 	/* saddr may be unspec; make_mp() will handle this */
   1048  11042      Erik 	connp->conn_saddr_v6 = sctp->sctp_primary->saddr;
   1049  11042      Erik 	connp->conn_laddr_v6 = connp->conn_saddr_v6;
   1050      0    stevel 	if (IN6_IS_ADDR_V4MAPPED(&sctp->sctp_primary->faddr)) {
   1051  11042      Erik 		if (!is_system_labeled() ||
   1052  11042      Erik 		    sctp_v4_label(sctp, sctp->sctp_primary) == 0) {
   1053   1676       jpk 			gotv4 = 1;
   1054  11042      Erik 			if (connp->conn_family == AF_INET) {
   1055  11042      Erik 				goto done;
   1056   1676       jpk 			}
   1057      0    stevel 		}
   1058      0    stevel 	} else {
   1059  11042      Erik 		if (!is_system_labeled() ||
   1060  11042      Erik 		    sctp_v6_label(sctp, sctp->sctp_primary) == 0) {
   1061   1676       jpk 			gotv6 = 1;
   1062  11042      Erik 		}
   1063      0    stevel 	}
   1064      0    stevel 
   1065      0    stevel 	for (fp = sctp->sctp_faddrs; fp; fp = fp->next) {
   1066      0    stevel 		if (!gotv4 && IN6_IS_ADDR_V4MAPPED(&fp->faddr)) {
   1067  11042      Erik 			if (!is_system_labeled() ||
   1068  11042      Erik 			    sctp_v4_label(sctp, fp) == 0) {
   1069   1676       jpk 				gotv4 = 1;
   1070  11042      Erik 				if (connp->conn_family == AF_INET || gotv6) {
   1071   1676       jpk 					break;
   1072   1676       jpk 				}
   1073      0    stevel 			}
   1074   2283  kp158701 		} else if (!gotv6 && !IN6_IS_ADDR_V4MAPPED(&fp->faddr)) {
   1075  11042      Erik 			if (!is_system_labeled() ||
   1076  11042      Erik 			    sctp_v6_label(sctp, fp) == 0) {
   1077   1676       jpk 				gotv6 = 1;
   1078   1676       jpk 				if (gotv4)
   1079   1676       jpk 					break;
   1080      0    stevel 			}
   1081      0    stevel 		}
   1082      0    stevel 	}
   1083      0    stevel 
   1084  11042      Erik done:
   1085   1676       jpk 	if (!gotv4 && !gotv6)
   1086   1676       jpk 		return (EACCES);
   1087   1676       jpk 
   1088   1676       jpk 	return (0);
   1089      0    stevel }
   1090      0    stevel 
   1091   8549    George /*
   1092   8549    George  * got_errchunk is set B_TRUE only if called from validate_init_params(), when
   1093   8549    George  * an ERROR chunk is already prepended the size of which needs updating for
   1094   8549    George  * additional unrecognized parameters. Other callers either prepend the ERROR
   1095   8549    George  * chunk with the correct size after calling this function, or they are calling
   1096   8549    George  * to add an invalid parameter to an INIT_ACK chunk, in that case no ERROR chunk
   1097   8549    George  * exists, the CAUSE blocks go into the INIT_ACK directly.
   1098   8549    George  *
   1099   8549    George  * *errmp will be non-NULL both when adding an additional CAUSE block to an
   1100   8549    George  * existing prepended COOKIE ERROR chunk (processing params of an INIT_ACK),
   1101   8549    George  * and when adding unrecognized parameters after the first, to an INIT_ACK
   1102   8549    George  * (processing params of an INIT chunk).
   1103   8549    George  */
   1104      0    stevel void
   1105   8549    George sctp_add_unrec_parm(sctp_parm_hdr_t *uph, mblk_t **errmp,
   1106   8549    George     boolean_t got_errchunk)
   1107      0    stevel {
   1108      0    stevel 	mblk_t *mp;
   1109      0    stevel 	sctp_parm_hdr_t *ph;
   1110      0    stevel 	size_t len;
   1111      0    stevel 	int pad;
   1112   8153    George 	sctp_chunk_hdr_t *ecp;
   1113      0    stevel 
   1114      0    stevel 	len = sizeof (*ph) + ntohs(uph->sph_len);
   1115   8153    George 	if ((pad = len % SCTP_ALIGN) != 0) {
   1116   8153    George 		pad = SCTP_ALIGN - pad;
   1117      0    stevel 		len += pad;
   1118      0    stevel 	}
   1119      0    stevel 	mp = allocb(len, BPRI_MED);
   1120      0    stevel 	if (mp == NULL) {
   1121      0    stevel 		return;
   1122      0    stevel 	}
   1123      0    stevel 
   1124      0    stevel 	ph = (sctp_parm_hdr_t *)(mp->b_rptr);
   1125      0    stevel 	ph->sph_type = htons(PARM_UNRECOGNIZED);
   1126      0    stevel 	ph->sph_len = htons(len - pad);
   1127      0    stevel 
   1128      0    stevel 	/* copy in the unrecognized parameter */
   1129      0    stevel 	bcopy(uph, ph + 1, ntohs(uph->sph_len));
   1130      0    stevel 
   1131   8153    George 	if (pad != 0)
   1132   8153    George 		bzero((mp->b_rptr + len - pad), pad);
   1133   8153    George 
   1134      0    stevel 	mp->b_wptr = mp->b_rptr + len;
   1135      0    stevel 	if (*errmp != NULL) {
   1136   8153    George 		/*
   1137   8549    George 		 * Update total length if an ERROR chunk, then link
   1138   8549    George 		 * this CAUSE block to the possible chain of CAUSE
   1139   8549    George 		 * blocks attached to the ERROR chunk or INIT_ACK
   1140   8549    George 		 * being created.
   1141   8153    George 		 */
   1142   8549    George 		if (got_errchunk) {
   1143   8549    George 			/* ERROR chunk already prepended */
   1144   8549    George 			ecp = (sctp_chunk_hdr_t *)((*errmp)->b_rptr);
   1145   8549    George 			ecp->sch_len = htons(ntohs(ecp->sch_len) + len);
   1146   8549    George 		}
   1147      0    stevel 		linkb(*errmp, mp);
   1148      0    stevel 	} else {
   1149      0    stevel 		*errmp = mp;
   1150      0    stevel 	}
   1151      0    stevel }
   1152      0    stevel 
   1153      0    stevel /*
   1154      0    stevel  * o Bounds checking
   1155      0    stevel  * o Updates remaining
   1156      0    stevel  * o Checks alignment
   1157      0    stevel  */
   1158      0    stevel sctp_parm_hdr_t *
   1159      0    stevel sctp_next_parm(sctp_parm_hdr_t *current, ssize_t *remaining)
   1160      0    stevel {
   1161      0    stevel 	int pad;
   1162      0    stevel 	uint16_t len;
   1163      0    stevel 
   1164      0    stevel 	len = ntohs(current->sph_len);
   1165      0    stevel 	*remaining -= len;
   1166      0    stevel 	if (*remaining < sizeof (*current) || len < sizeof (*current)) {
   1167      0    stevel 		return (NULL);
   1168      0    stevel 	}
   1169      0    stevel 	if ((pad = len & (SCTP_ALIGN - 1)) != 0) {
   1170      0    stevel 		pad = SCTP_ALIGN - pad;
   1171      0    stevel 		*remaining -= pad;
   1172      0    stevel 	}
   1173      0    stevel 	/*LINTED pointer cast may result in improper alignment*/
   1174      0    stevel 	current = (sctp_parm_hdr_t *)((char *)current + len + pad);
   1175      0    stevel 	return (current);
   1176      0    stevel }
   1177      0    stevel 
   1178      0    stevel /*
   1179      0    stevel  * Sets the address parameters given in the INIT chunk into sctp's
   1180      0    stevel  * faddrs; if psctp is non-NULL, copies psctp's saddrs. If there are
   1181      0    stevel  * no address parameters in the INIT chunk, a single faddr is created
   1182      0    stevel  * from the ip hdr at the beginning of pkt.
   1183      0    stevel  * If there already are existing addresses hanging from sctp, merge
   1184      0    stevel  * them in, if the old info contains addresses which are not present
   1185      0    stevel  * in this new info, get rid of them, and clean the pointers if there's
   1186      0    stevel  * messages which have this as their target address.
   1187      0    stevel  *
   1188    432  vi117747  * We also re-adjust the source address list here since the list may
   1189    432  vi117747  * contain more than what is actually part of the association. If
   1190    432  vi117747  * we get here from sctp_send_cookie_echo(), we are on the active
   1191    432  vi117747  * side and psctp will be NULL and ich will be the INIT-ACK chunk.
   1192    432  vi117747  * If we get here from sctp_accept_comm(), ich will be the INIT chunk
   1193    432  vi117747  * and psctp will the listening endpoint.
   1194    432  vi117747  *
   1195    432  vi117747  * INIT processing: When processing the INIT we inherit the src address
   1196    432  vi117747  * list from the listener. For a loopback or linklocal association, we
   1197    432  vi117747  * delete the list and just take the address from the IP header (since
   1198    432  vi117747  * that's how we created the INIT-ACK). Additionally, for loopback we
   1199    432  vi117747  * ignore the address params in the INIT. For determining which address
   1200    432  vi117747  * types were sent in the INIT-ACK we follow the same logic as in
   1201    432  vi117747  * creating the INIT-ACK. We delete addresses of the type that are not
   1202    432  vi117747  * supported by the peer.
   1203    432  vi117747  *
   1204    432  vi117747  * INIT-ACK processing: When processing the INIT-ACK since we had not
   1205    432  vi117747  * included addr params for loopback or linklocal addresses when creating
   1206    432  vi117747  * the INIT, we just use the address from the IP header. Further, for
   1207    432  vi117747  * loopback we ignore the addr param list. We mark addresses of the
   1208    432  vi117747  * type not supported by the peer as unconfirmed.
   1209    432  vi117747  *
   1210    432  vi117747  * In case of INIT processing we look for supported address types in the
   1211    432  vi117747  * supported address param, if present. In both cases the address type in
   1212    432  vi117747  * the IP header is supported as well as types for addresses in the param
   1213    432  vi117747  * list, if any.
   1214    432  vi117747  *
   1215    432  vi117747  * Once we have the supported address types sctp_check_saddr() runs through
   1216    432  vi117747  * the source address list and deletes or marks as unconfirmed address of
   1217    432  vi117747  * types not supported by the peer.
   1218    432  vi117747  *
   1219      0    stevel  * Returns 0 on success, sys errno on failure
   1220      0    stevel  */
   1221      0    stevel int
   1222      0    stevel sctp_get_addrparams(sctp_t *sctp, sctp_t *psctp, mblk_t *pkt,
   1223      0    stevel     sctp_chunk_hdr_t *ich, uint_t *sctp_options)
   1224      0    stevel {
   1225      0    stevel 	sctp_init_chunk_t	*init;
   1226      0    stevel 	ipha_t			*iph;
   1227      0    stevel 	ip6_t			*ip6h;
   1228    432  vi117747 	in6_addr_t		hdrsaddr[1];
   1229    432  vi117747 	in6_addr_t		hdrdaddr[1];
   1230      0    stevel 	sctp_parm_hdr_t		*ph;
   1231      0    stevel 	ssize_t			remaining;
   1232      0    stevel 	int			isv4;
   1233      0    stevel 	int			err;
   1234      0    stevel 	sctp_faddr_t		*fp;
   1235    432  vi117747 	int			supp_af = 0;
   1236    432  vi117747 	boolean_t		check_saddr = B_TRUE;
   1237    852  vi117747 	in6_addr_t		curaddr;
   1238   3448  dh155122 	sctp_stack_t		*sctps = sctp->sctp_sctps;
   1239  11042      Erik 	conn_t			*connp = sctp->sctp_connp;
   1240      0    stevel 
   1241      0    stevel 	if (sctp_options != NULL)
   1242      0    stevel 		*sctp_options = 0;
   1243      0    stevel 
   1244    432  vi117747 	/* extract the address from the IP header */
   1245    432  vi117747 	isv4 = (IPH_HDR_VERSION(pkt->b_rptr) == IPV4_VERSION);
   1246    432  vi117747 	if (isv4) {
   1247    432  vi117747 		iph = (ipha_t *)pkt->b_rptr;
   1248    432  vi117747 		IN6_IPADDR_TO_V4MAPPED(iph->ipha_src, hdrsaddr);
   1249    432  vi117747 		IN6_IPADDR_TO_V4MAPPED(iph->ipha_dst, hdrdaddr);
   1250    432  vi117747 		supp_af |= PARM_SUPP_V4;
   1251    432  vi117747 	} else {
   1252    432  vi117747 		ip6h = (ip6_t *)pkt->b_rptr;
   1253    432  vi117747 		hdrsaddr[0] = ip6h->ip6_src;
   1254    432  vi117747 		hdrdaddr[0] = ip6h->ip6_dst;
   1255    432  vi117747 		supp_af |= PARM_SUPP_V6;
   1256    432  vi117747 	}
   1257    432  vi117747 
   1258    432  vi117747 	/*
   1259    432  vi117747 	 * Unfortunately, we can't delay this because adding an faddr
   1260    432  vi117747 	 * looks for the presence of the source address (from the ire
   1261    432  vi117747 	 * for the faddr) in the source address list. We could have
   1262    432  vi117747 	 * delayed this if, say, this was a loopback/linklocal connection.
   1263    432  vi117747 	 * Now, we just end up nuking this list and taking the addr from
   1264    432  vi117747 	 * the IP header for loopback/linklocal.
   1265    432  vi117747 	 */
   1266      0    stevel 	if (psctp != NULL && psctp->sctp_nsaddrs > 0) {
   1267      0    stevel 		ASSERT(sctp->sctp_nsaddrs == 0);
   1268      0    stevel 
   1269      0    stevel 		err = sctp_dup_saddrs(psctp, sctp, KM_NOSLEEP);
   1270      0    stevel 		if (err != 0)
   1271      0    stevel 			return (err);
   1272      0    stevel 	}
   1273    432  vi117747 	/*
   1274    432  vi117747 	 * We will add the faddr before parsing the address list as this
   1275    432  vi117747 	 * might be a loopback connection and we would not have to
   1276    432  vi117747 	 * go through the list.
   1277    432  vi117747 	 *
   1278    432  vi117747 	 * Make sure the header's addr is in the list
   1279    432  vi117747 	 */
   1280    432  vi117747 	fp = sctp_lookup_faddr(sctp, hdrsaddr);
   1281    432  vi117747 	if (fp == NULL) {
   1282    432  vi117747 		/* not included; add it now */
   1283   1735    kcpoon 		err = sctp_add_faddr(sctp, hdrsaddr, KM_NOSLEEP, B_TRUE);
   1284   1676       jpk 		if (err != 0)
   1285   1676       jpk 			return (err);
   1286      0    stevel 
   1287    432  vi117747 		/* sctp_faddrs will be the hdr addr */
   1288    432  vi117747 		fp = sctp->sctp_faddrs;
   1289      0    stevel 	}
   1290    432  vi117747 	/* make the header addr the primary */
   1291    852  vi117747 
   1292    852  vi117747 	if (cl_sctp_assoc_change != NULL && psctp == NULL)
   1293    852  vi117747 		curaddr = sctp->sctp_current->faddr;
   1294    852  vi117747 
   1295    432  vi117747 	sctp->sctp_primary = fp;
   1296    432  vi117747 	sctp->sctp_current = fp;
   1297    432  vi117747 	sctp->sctp_mss = fp->sfa_pmss;
   1298      0    stevel 
   1299    432  vi117747 	/* For loopback connections & linklocal get address from the header */
   1300    432  vi117747 	if (sctp->sctp_loopback || sctp->sctp_linklocal) {
   1301    432  vi117747 		if (sctp->sctp_nsaddrs != 0)
   1302    432  vi117747 			sctp_free_saddrs(sctp);
   1303    852  vi117747 		if ((err = sctp_saddr_add_addr(sctp, hdrdaddr, 0)) != 0)
   1304    432  vi117747 			return (err);
   1305    432  vi117747 		/* For loopback ignore address list */
   1306    432  vi117747 		if (sctp->sctp_loopback)
   1307    432  vi117747 			return (0);
   1308    432  vi117747 		check_saddr = B_FALSE;
   1309    432  vi117747 	}
   1310      0    stevel 
   1311      0    stevel 	/* Walk the params in the INIT [ACK], pulling out addr params */
   1312      0    stevel 	remaining = ntohs(ich->sch_len) - sizeof (*ich) -
   1313      0    stevel 	    sizeof (sctp_init_chunk_t);
   1314      0    stevel 	if (remaining < sizeof (*ph)) {
   1315    432  vi117747 		if (check_saddr) {
   1316    432  vi117747 			sctp_check_saddr(sctp, supp_af, psctp == NULL ?
   1317   4818    kcpoon 			    B_FALSE : B_TRUE, hdrdaddr);
   1318    432  vi117747 		}
   1319    852  vi117747 		ASSERT(sctp_saddr_lookup(sctp, hdrdaddr, 0) != NULL);
   1320    432  vi117747 		return (0);
   1321      0    stevel 	}
   1322    432  vi117747 
   1323      0    stevel 	init = (sctp_init_chunk_t *)(ich + 1);
   1324      0    stevel 	ph = (sctp_parm_hdr_t *)(init + 1);
   1325      0    stevel 
   1326    432  vi117747 	/* params will have already been byteordered when validating */
   1327      0    stevel 	while (ph != NULL) {
   1328    432  vi117747 		if (ph->sph_type == htons(PARM_SUPP_ADDRS)) {
   1329    432  vi117747 			int		plen;
   1330    432  vi117747 			uint16_t	*p;
   1331    432  vi117747 			uint16_t	addrtype;
   1332    432  vi117747 
   1333    432  vi117747 			ASSERT(psctp != NULL);
   1334    432  vi117747 			plen = ntohs(ph->sph_len);
   1335    432  vi117747 			p = (uint16_t *)(ph + 1);
   1336    432  vi117747 			while (plen > 0) {
   1337    432  vi117747 				addrtype = ntohs(*p);
   1338    432  vi117747 				switch (addrtype) {
   1339    432  vi117747 					case PARM_ADDR6:
   1340    432  vi117747 						supp_af |= PARM_SUPP_V6;
   1341    432  vi117747 						break;
   1342    432  vi117747 					case PARM_ADDR4:
   1343    432  vi117747 						supp_af |= PARM_SUPP_V4;
   1344    432  vi117747 						break;
   1345    432  vi117747 					default:
   1346    432  vi117747 						break;
   1347    432  vi117747 				}
   1348    432  vi117747 				p++;
   1349    432  vi117747 				plen -= sizeof (*p);
   1350    432  vi117747 			}
   1351    432  vi117747 		} else if (ph->sph_type == htons(PARM_ADDR4)) {
   1352      0    stevel 			if (remaining >= PARM_ADDR4_LEN) {
   1353      0    stevel 				in6_addr_t addr;
   1354      0    stevel 				ipaddr_t ta;
   1355      0    stevel 
   1356    432  vi117747 				supp_af |= PARM_SUPP_V4;
   1357      0    stevel 				/*
   1358      0    stevel 				 * Screen out broad/multicasts & loopback.
   1359      0    stevel 				 * If the endpoint only accepts v6 address,
   1360      0    stevel 				 * go to the next one.
   1361   4818    kcpoon 				 *
   1362   4818    kcpoon 				 * Subnet broadcast check is done in
   1363   4818    kcpoon 				 * sctp_add_faddr().  If the address is
   1364   4818    kcpoon 				 * a broadcast address, it won't be added.
   1365      0    stevel 				 */
   1366      0    stevel 				bcopy(ph + 1, &ta, sizeof (ta));
   1367      0    stevel 				if (ta == 0 ||
   1368      0    stevel 				    ta == INADDR_BROADCAST ||
   1369      0    stevel 				    ta == htonl(INADDR_LOOPBACK) ||
   1370  11042      Erik 				    CLASSD(ta) || connp->conn_ipv6_v6only) {
   1371      0    stevel 					goto next;
   1372      0    stevel 				}
   1373      0    stevel 				IN6_INADDR_TO_V4MAPPED((struct in_addr *)
   1374      0    stevel 				    (ph + 1), &addr);
   1375   4818    kcpoon 
   1376      0    stevel 				/* Check for duplicate. */
   1377      0    stevel 				if (sctp_lookup_faddr(sctp, &addr) != NULL)
   1378      0    stevel 					goto next;
   1379      0    stevel 
   1380      0    stevel 				/* OK, add it to the faddr set */
   1381   1735    kcpoon 				err = sctp_add_faddr(sctp, &addr, KM_NOSLEEP,
   1382   1735    kcpoon 				    B_FALSE);
   1383   4818    kcpoon 				/* Something is wrong...  Try the next one. */
   1384   1676       jpk 				if (err != 0)
   1385   4818    kcpoon 					goto next;
   1386      0    stevel 			}
   1387      0    stevel 		} else if (ph->sph_type == htons(PARM_ADDR6) &&
   1388  11042      Erik 		    connp->conn_family == AF_INET6) {
   1389      0    stevel 			/* An v4 socket should not take v6 addresses. */
   1390      0    stevel 			if (remaining >= PARM_ADDR6_LEN) {
   1391      0    stevel 				in6_addr_t *addr6;
   1392      0    stevel 
   1393    432  vi117747 				supp_af |= PARM_SUPP_V6;
   1394      0    stevel 				addr6 = (in6_addr_t *)(ph + 1);
   1395      0    stevel 				/*
   1396      0    stevel 				 * Screen out link locals, mcast, loopback
   1397      0    stevel 				 * and bogus v6 address.
   1398      0    stevel 				 */
   1399      0    stevel 				if (IN6_IS_ADDR_LINKLOCAL(addr6) ||
   1400      0    stevel 				    IN6_IS_ADDR_MULTICAST(addr6) ||
   1401      0    stevel 				    IN6_IS_ADDR_LOOPBACK(addr6) ||
   1402      0    stevel 				    IN6_IS_ADDR_V4MAPPED(addr6)) {
   1403      0    stevel 					goto next;
   1404      0    stevel 				}
   1405      0    stevel 				/* Check for duplicate. */
   1406      0    stevel 				if (sctp_lookup_faddr(sctp, addr6) != NULL)
   1407      0    stevel 					goto next;
   1408      0    stevel 
   1409   1676       jpk 				err = sctp_add_faddr(sctp,
   1410   1735    kcpoon 				    (in6_addr_t *)(ph + 1), KM_NOSLEEP,
   1411   1735    kcpoon 				    B_FALSE);
   1412   4818    kcpoon 				/* Something is wrong...  Try the next one. */
   1413   1676       jpk 				if (err != 0)
   1414   4818    kcpoon 					goto next;
   1415      0    stevel 			}
   1416      0    stevel 		} else if (ph->sph_type == htons(PARM_FORWARD_TSN)) {
   1417      0    stevel 			if (sctp_options != NULL)
   1418      0    stevel 				*sctp_options |= SCTP_PRSCTP_OPTION;
   1419      0    stevel 		} /* else; skip */
   1420      0    stevel 
   1421      0    stevel next:
   1422      0    stevel 		ph = sctp_next_parm(ph, &remaining);
   1423      0    stevel 	}
   1424    432  vi117747 	if (check_saddr) {
   1425    432  vi117747 		sctp_check_saddr(sctp, supp_af, psctp == NULL ? B_FALSE :
   1426   4818    kcpoon 		    B_TRUE, hdrdaddr);
   1427      0    stevel 	}
   1428    852  vi117747 	ASSERT(sctp_saddr_lookup(sctp, hdrdaddr, 0) != NULL);
   1429    852  vi117747 	/*
   1430    852  vi117747 	 * We have the right address list now, update clustering's
   1431    852  vi117747 	 * knowledge because when we sent the INIT we had just added
   1432    852  vi117747 	 * the address the INIT was sent to.
   1433    852  vi117747 	 */
   1434    852  vi117747 	if (psctp == NULL && cl_sctp_assoc_change != NULL) {
   1435    852  vi117747 		uchar_t	*alist;
   1436    852  vi117747 		size_t	asize;
   1437    852  vi117747 		uchar_t	*dlist;
   1438    852  vi117747 		size_t	dsize;
   1439    852  vi117747 
   1440    852  vi117747 		asize = sizeof (in6_addr_t) * sctp->sctp_nfaddrs;
   1441    852  vi117747 		alist = kmem_alloc(asize, KM_NOSLEEP);
   1442   1735    kcpoon 		if (alist == NULL) {
   1443   3448  dh155122 			SCTP_KSTAT(sctps, sctp_cl_assoc_change);
   1444    852  vi117747 			return (ENOMEM);
   1445   1735    kcpoon 		}
   1446    852  vi117747 		/*
   1447    852  vi117747 		 * Just include the address the INIT was sent to in the
   1448    852  vi117747 		 * delete list and send the entire faddr list. We could
   1449    852  vi117747 		 * do it differently (i.e include all the addresses in the
   1450    852  vi117747 		 * add list even if it contains the original address OR
   1451    852  vi117747 		 * remove the original address from the add list etc.), but
   1452    852  vi117747 		 * this seems reasonable enough.
   1453    852  vi117747 		 */
   1454    852  vi117747 		dsize = sizeof (in6_addr_t);
   1455    852  vi117747 		dlist = kmem_alloc(dsize, KM_NOSLEEP);
   1456    852  vi117747 		if (dlist == NULL) {
   1457    852  vi117747 			kmem_free(alist, asize);
   1458   3448  dh155122 			SCTP_KSTAT(sctps, sctp_cl_assoc_change);
   1459    852  vi117747 			return (ENOMEM);
   1460    852  vi117747 		}
   1461    852  vi117747 		bcopy(&curaddr, dlist, sizeof (curaddr));
   1462    852  vi117747 		sctp_get_faddr_list(sctp, alist, asize);
   1463  11042      Erik 		(*cl_sctp_assoc_change)(connp->conn_family, alist, asize,
   1464    852  vi117747 		    sctp->sctp_nfaddrs, dlist, dsize, 1, SCTP_CL_PADDR,
   1465    852  vi117747 		    (cl_sctp_handle_t)sctp);
   1466    852  vi117747 		/* alist and dlist will be freed by the clustering module */
   1467    852  vi117747 	}
   1468      0    stevel 	return (0);
   1469      0    stevel }
   1470      0    stevel 
   1471      0    stevel /*
   1472      0    stevel  * Returns 0 if the check failed and the restart should be refused,
   1473      0    stevel  * 1 if the check succeeded.
   1474      0    stevel  */
   1475      0    stevel int
   1476      0    stevel sctp_secure_restart_check(mblk_t *pkt, sctp_chunk_hdr_t *ich, uint32_t ports,
   1477  11042      Erik     int sleep, sctp_stack_t *sctps, ip_recv_attr_t *ira)
   1478      0    stevel {
   1479   4964    kcpoon 	sctp_faddr_t *fp, *fphead = NULL;
   1480      0    stevel 	sctp_parm_hdr_t *ph;
   1481      0    stevel 	ssize_t remaining;
   1482      0    stevel 	int isv4;
   1483      0    stevel 	ipha_t *iph;
   1484      0    stevel 	ip6_t *ip6h;
   1485      0    stevel 	in6_addr_t hdraddr[1];
   1486      0    stevel 	int retval = 0;
   1487      0    stevel 	sctp_tf_t *tf;
   1488      0    stevel 	sctp_t *sctp;
   1489      0    stevel 	int compres;
   1490      0    stevel 	sctp_init_chunk_t *init;
   1491      0    stevel 	int nadded = 0;
   1492      0    stevel 
   1493      0    stevel 	/* extract the address from the IP header */
   1494      0    stevel 	isv4 = (IPH_HDR_VERSION(pkt->b_rptr) == IPV4_VERSION);
   1495      0    stevel 	if (isv4) {
   1496      0    stevel 		iph = (ipha_t *)pkt->b_rptr;
   1497      0    stevel 		IN6_IPADDR_TO_V4MAPPED(iph->ipha_src, hdraddr);
   1498      0    stevel 	} else {
   1499      0    stevel 		ip6h = (ip6_t *)pkt->b_rptr;
   1500      0    stevel 		hdraddr[0] = ip6h->ip6_src;
   1501      0    stevel 	}
   1502      0    stevel 
   1503      0    stevel 	/* Walk the params in the INIT [ACK], pulling out addr params */
   1504      0    stevel 	remaining = ntohs(ich->sch_len) - sizeof (*ich) -
   1505      0    stevel 	    sizeof (sctp_init_chunk_t);
   1506      0    stevel 	if (remaining < sizeof (*ph)) {
   1507      0    stevel 		/* no parameters; restart OK */
   1508      0    stevel 		return (1);
   1509      0    stevel 	}
   1510      0    stevel 	init = (sctp_init_chunk_t *)(ich + 1);
   1511      0    stevel 	ph = (sctp_parm_hdr_t *)(init + 1);
   1512      0    stevel 
   1513      0    stevel 	while (ph != NULL) {
   1514   4964    kcpoon 		sctp_faddr_t *fpa = NULL;
   1515   4964    kcpoon 
   1516      0    stevel 		/* params will have already been byteordered when validating */
   1517      0    stevel 		if (ph->sph_type == htons(PARM_ADDR4)) {
   1518      0    stevel 			if (remaining >= PARM_ADDR4_LEN) {
   1519      0    stevel 				in6_addr_t addr;
   1520      0    stevel 				IN6_INADDR_TO_V4MAPPED((struct in_addr *)
   1521      0    stevel 				    (ph + 1), &addr);
   1522      0    stevel 				fpa = kmem_cache_alloc(sctp_kmem_faddr_cache,
   1523      0    stevel 				    sleep);
   1524   4964    kcpoon 				if (fpa == NULL) {
   1525      0    stevel 					goto done;
   1526      0    stevel 				}
   1527      0    stevel 				bzero(fpa, sizeof (*fpa));
   1528      0    stevel 				fpa->faddr = addr;
   1529      0    stevel 				fpa->next = NULL;
   1530      0    stevel 			}
   1531      0    stevel 		} else if (ph->sph_type == htons(PARM_ADDR6)) {
   1532      0    stevel 			if (remaining >= PARM_ADDR6_LEN) {
   1533      0    stevel 				fpa = kmem_cache_alloc(sctp_kmem_faddr_cache,
   1534      0    stevel 				    sleep);
   1535   4964    kcpoon 				if (fpa == NULL) {
   1536      0    stevel 					goto done;
   1537      0    stevel 				}
   1538      0    stevel 				bzero(fpa, sizeof (*fpa));
   1539      0    stevel 				bcopy(ph + 1, &fpa->faddr,
   1540      0    stevel 				    sizeof (fpa->faddr));
   1541      0    stevel 				fpa->next = NULL;
   1542      0    stevel 			}
   1543      0    stevel 		}
   1544      0    stevel 		/* link in the new addr, if it was an addr param */
   1545   4964    kcpoon 		if (fpa != NULL) {
   1546   4964    kcpoon 			if (fphead == NULL) {
   1547      0    stevel 				fphead = fpa;
   1548      0    stevel 			} else {
   1549   4964    kcpoon 				fpa->next = fphead;
   1550   4964    kcpoon 				fphead = fpa;
   1551      0    stevel 			}
   1552      0    stevel 		}
   1553      0    stevel 
   1554      0    stevel 		ph = sctp_next_parm(ph, &remaining);
   1555      0    stevel 	}
   1556      0    stevel 
   1557      0    stevel 	if (fphead == NULL) {
   1558      0    stevel 		/* no addr parameters; restart OK */
   1559      0    stevel 		return (1);
   1560      0    stevel 	}
   1561      0    stevel 
   1562      0    stevel 	/*
   1563      0    stevel 	 * got at least one; make sure the header's addr is
   1564      0    stevel 	 * in the list
   1565      0    stevel 	 */
   1566      0    stevel 	fp = sctp_lookup_faddr_nosctp(fphead, hdraddr);
   1567   4964    kcpoon 	if (fp == NULL) {
   1568      0    stevel 		/* not included; add it now */
   1569      0    stevel 		fp = kmem_cache_alloc(sctp_kmem_faddr_cache, sleep);
   1570   4964    kcpoon 		if (fp == NULL) {
   1571      0    stevel 			goto done;
   1572      0    stevel 		}
   1573      0    stevel 		bzero(fp, sizeof (*fp));
   1574      0    stevel 		fp->faddr = *hdraddr;
   1575      0    stevel 		fp->next = fphead;
   1576      0    stevel 		fphead = fp;
   1577      0    stevel 	}
   1578      0    stevel 
   1579      0    stevel 	/*
   1580      0    stevel 	 * Now, we can finally do the check: For each sctp instance
   1581      0    stevel 	 * on the hash line for ports, compare its faddr set against
   1582      0    stevel 	 * the new one. If the new one is a strict subset of any
   1583      0    stevel 	 * existing sctp's faddrs, the restart is OK. However, if there
   1584      0    stevel 	 * is an overlap, this could be an attack, so return failure.
   1585      0    stevel 	 * If all sctp's faddrs are disjoint, this is a legitimate new
   1586      0    stevel 	 * association.
   1587      0    stevel 	 */
   1588   3448  dh155122 	tf = &(sctps->sctps_conn_fanout[SCTP_CONN_HASH(sctps, ports)]);
   1589      0    stevel 	mutex_enter(&tf->tf_lock);
   1590      0    stevel 
   1591      0    stevel 	for (sctp = tf->tf_sctp; sctp; sctp = sctp->sctp_conn_hash_next) {
   1592  11042      Erik 		if (ports != sctp->sctp_connp->conn_ports) {
   1593      0    stevel 			continue;
   1594      0    stevel 		}
   1595      0    stevel 		compres = sctp_compare_faddrsets(fphead, sctp->sctp_faddrs);
   1596      0    stevel 		if (compres <= SCTP_ADDR_SUBSET) {
   1597      0    stevel 			retval = 1;
   1598      0    stevel 			mutex_exit(&tf->tf_lock);
   1599      0    stevel 			goto done;
   1600      0    stevel 		}
   1601      0    stevel 		if (compres == SCTP_ADDR_OVERLAP) {
   1602      0    stevel 			dprint(1,
   1603      0    stevel 			    ("new assoc from %x:%x:%x:%x overlaps with %p\n",
   1604   1676       jpk 			    SCTP_PRINTADDR(*hdraddr), (void *)sctp));
   1605      0    stevel 			/*
   1606      0    stevel 			 * While we still hold the lock, we need to
   1607      0    stevel 			 * figure out which addresses have been
   1608      0    stevel 			 * added so we can include them in the abort
   1609      0    stevel 			 * we will send back. Since these faddrs will
   1610      0    stevel 			 * never be used, we overload the rto field
   1611      0    stevel 			 * here, setting it to 0 if the address was
   1612      0    stevel 			 * not added, 1 if it was added.
   1613      0    stevel 			 */
   1614      0    stevel 			for (fp = fphead; fp; fp = fp->next) {
   1615      0    stevel 				if (sctp_lookup_faddr(sctp, &fp->faddr)) {
   1616      0    stevel 					fp->rto = 0;
   1617      0    stevel 				} else {
   1618      0    stevel 					fp->rto = 1;
   1619      0    stevel 					nadded++;
   1620      0    stevel 				}
   1621      0    stevel 			}
   1622      0    stevel 			mutex_exit(&tf->tf_lock);
   1623      0    stevel 			goto done;
   1624      0    stevel 		}
   1625      0    stevel 	}
   1626      0    stevel 	mutex_exit(&tf->tf_lock);
   1627      0    stevel 
   1628      0    stevel 	/* All faddrs are disjoint; legit new association */
   1629      0    stevel 	retval = 1;
   1630      0    stevel 
   1631      0    stevel done:
   1632      0    stevel 	/* If are attempted adds, send back an abort listing the addrs */
   1633      0    stevel 	if (nadded > 0) {
   1634      0    stevel 		void *dtail;
   1635      0    stevel 		size_t dlen;
   1636      0    stevel 
   1637      0    stevel 		dtail = kmem_alloc(PARM_ADDR6_LEN * nadded, KM_NOSLEEP);
   1638      0    stevel 		if (dtail == NULL) {
   1639      0    stevel 			goto cleanup;
   1640      0    stevel 		}
   1641      0    stevel 
   1642      0    stevel 		ph = dtail;
   1643      0    stevel 		dlen = 0;
   1644      0    stevel 		for (fp = fphead; fp; fp = fp->next) {
   1645      0    stevel 			if (fp->rto == 0) {
   1646      0    stevel 				continue;
   1647      0    stevel 			}
   1648      0    stevel 			if (IN6_IS_ADDR_V4MAPPED(&fp->faddr)) {
   1649      0    stevel 				ipaddr_t addr4;
   1650      0    stevel 
   1651      0    stevel 				ph->sph_type = htons(PARM_ADDR4);
   1652      0    stevel 				ph->sph_len = htons(PARM_ADDR4_LEN);
   1653      0    stevel 				IN6_V4MAPPED_TO_IPADDR(&fp->faddr, addr4);
   1654      0    stevel 				ph++;
   1655      0    stevel 				bcopy(&addr4, ph, sizeof (addr4));
   1656      0    stevel 				ph = (sctp_parm_hdr_t *)
   1657      0    stevel 				    ((char *)ph + sizeof (addr4));
   1658      0    stevel 				dlen += PARM_ADDR4_LEN;
   1659      0    stevel 			} else {
   1660      0    stevel 				ph->sph_type = htons(PARM_ADDR6);
   1661      0    stevel 				ph->sph_len = htons(PARM_ADDR6_LEN);
   1662      0    stevel 				ph++;
   1663      0    stevel 				bcopy(&fp->faddr, ph, sizeof (fp->faddr));
   1664      0    stevel 				ph = (sctp_parm_hdr_t *)
   1665      0    stevel 				    ((char *)ph + sizeof (fp->faddr));
   1666      0    stevel 				dlen += PARM_ADDR6_LEN;
   1667      0    stevel 			}
   1668      0    stevel 		}
   1669      0    stevel 
   1670      0    stevel 		/* Send off the abort */
   1671      0    stevel 		sctp_send_abort(sctp, sctp_init2vtag(ich),
   1672  11042      Erik 		    SCTP_ERR_RESTART_NEW_ADDRS, dtail, dlen, pkt, 0, B_TRUE,
   1673  11042      Erik 		    ira);
   1674      0    stevel 
   1675      0    stevel 		kmem_free(dtail, PARM_ADDR6_LEN * nadded);
   1676      0    stevel 	}
   1677      0    stevel 
   1678      0    stevel cleanup:
   1679      0    stevel 	/* Clean up */
   1680      0    stevel 	if (fphead) {
   1681      0    stevel 		sctp_faddr_t *fpn;
   1682      0    stevel 		for (fp = fphead; fp; fp = fpn) {
   1683      0    stevel 			fpn = fp->next;
   1684  11042      Erik 			if (fp->ixa != NULL) {
   1685  11042      Erik 				ixa_refrele(fp->ixa);
   1686  11042      Erik 				fp->ixa = NULL;
   1687  11042      Erik 			}
   1688      0    stevel 			kmem_cache_free(sctp_kmem_faddr_cache, fp);
   1689      0    stevel 		}
   1690      0    stevel 	}
   1691      0    stevel 
   1692      0    stevel 	return (retval);
   1693      0    stevel }
   1694      0    stevel 
   1695   1932  vi117747 /*
   1696   1932  vi117747  * Reset any state related to transmitted chunks.
   1697   1932  vi117747  */
   1698      0    stevel void
   1699      0    stevel sctp_congest_reset(sctp_t *sctp)
   1700      0    stevel {
   1701   1932  vi117747 	sctp_faddr_t	*fp;
   1702   3448  dh155122 	sctp_stack_t	*sctps = sctp->sctp_sctps;
   1703   1932  vi117747 	mblk_t		*mp;
   1704      0    stevel 
   1705   1932  vi117747 	for (fp = sctp->sctp_faddrs; fp != NULL; fp = fp->next) {
   1706   3448  dh155122 		fp->ssthresh = sctps->sctps_initial_mtu;
   1707   3795    kcpoon 		SET_CWND(fp, fp->sfa_pmss, sctps->sctps_slow_start_initial);
   1708      0    stevel 		fp->suna = 0;
   1709      0    stevel 		fp->pba = 0;
   1710      0    stevel 	}
   1711   1932  vi117747 	/*
   1712   1932  vi117747 	 * Clean up the transmit list as well since we have reset accounting
   1713   1932  vi117747 	 * on all the fps. Send event upstream, if required.
   1714   1932  vi117747 	 */
   1715   1932  vi117747 	while ((mp = sctp->sctp_xmit_head) != NULL) {
   1716   1932  vi117747 		sctp->sctp_xmit_head = mp->b_next;
   1717   1932  vi117747 		mp->b_next = NULL;
   1718   1932  vi117747 		if (sctp->sctp_xmit_head != NULL)
   1719   1932  vi117747 			sctp->sctp_xmit_head->b_prev = NULL;
   1720   1932  vi117747 		sctp_sendfail_event(sctp, mp, 0, B_TRUE);
   1721   1932  vi117747 	}
   1722   1932  vi117747 	sctp->sctp_xmit_head = NULL;
   1723   1932  vi117747 	sctp->sctp_xmit_tail = NULL;
   1724   1932  vi117747 	sctp->sctp_xmit_unacked = NULL;
   1725   1932  vi117747 
   1726   1932  vi117747 	sctp->sctp_unacked = 0;
   1727   1932  vi117747 	/*
   1728   1932  vi117747 	 * Any control message as well. We will clean-up this list as well.
   1729   1932  vi117747 	 * This contains any pending ASCONF request that we have queued/sent.
   1730   1932  vi117747 	 * If we do get an ACK we will just drop it. However, given that
   1731   1932  vi117747 	 * we are restarting chances are we aren't going to get any.
   1732   1932  vi117747 	 */
   1733   1932  vi117747 	if (sctp->sctp_cxmit_list != NULL)
   1734   1932  vi117747 		sctp_asconf_free_cxmit(sctp, NULL);
   1735   1932  vi117747 	sctp->sctp_cxmit_list = NULL;
   1736   1932  vi117747 	sctp->sctp_cchunk_pend = 0;
   1737   1932  vi117747 
   1738   1932  vi117747 	sctp->sctp_rexmitting = B_FALSE;
   1739   1932  vi117747 	sctp->sctp_rxt_nxttsn = 0;
   1740   1932  vi117747 	sctp->sctp_rxt_maxtsn = 0;
   1741   1932  vi117747 
   1742   1932  vi117747 	sctp->sctp_zero_win_probe = B_FALSE;
   1743      0    stevel }
   1744      0    stevel 
   1745      0    stevel static void
   1746   1735    kcpoon sctp_init_faddr(sctp_t *sctp, sctp_faddr_t *fp, in6_addr_t *addr,
   1747   1735    kcpoon     mblk_t *timer_mp)
   1748      0    stevel {
   1749   3448  dh155122 	sctp_stack_t	*sctps = sctp->sctp_sctps;
   1750   3448  dh155122 
   1751  11042      Erik 	ASSERT(fp->ixa != NULL);
   1752  11042      Erik 
   1753      0    stevel 	bcopy(addr, &fp->faddr, sizeof (*addr));
   1754      0    stevel 	if (IN6_IS_ADDR_V4MAPPED(addr)) {
   1755      0    stevel 		fp->isv4 = 1;
   1756      0    stevel 		/* Make sure that sfa_pmss is a multiple of SCTP_ALIGN. */
   1757   4691    kcpoon 		fp->sfa_pmss =
   1758   4691    kcpoon 		    (sctps->sctps_initial_mtu - sctp->sctp_hdr_len) &
   1759   4691    kcpoon 		    ~(SCTP_ALIGN - 1);
   1760  11042      Erik 		fp->ixa->ixa_flags |= IXAF_IS_IPV4;
   1761      0    stevel 	} else {
   1762      0    stevel 		fp->isv4 = 0;
   1763   3448  dh155122 		fp->sfa_pmss =
   1764   3448  dh155122 		    (sctps->sctps_initial_mtu - sctp->sctp_hdr6_len) &
   1765   3448  dh155122 		    ~(SCTP_ALIGN - 1);
   1766  11042      Erik 		fp->ixa->ixa_flags &= ~IXAF_IS_IPV4;
   1767      0    stevel 	}
   1768   3448  dh155122 	fp->cwnd = sctps->sctps_slow_start_initial * fp->sfa_pmss;
   1769      0    stevel 	fp->rto = MIN(sctp->sctp_rto_initial, sctp->sctp_init_rto_max);
   1770  10212    George 	SCTP_MAX_RTO(sctp, fp);
   1771      0    stevel 	fp->srtt = -1;
   1772      0    stevel 	fp->rtt_updates = 0;
   1773      0    stevel 	fp->strikes = 0;
   1774      0    stevel 	fp->max_retr = sctp->sctp_pp_max_rxt;
   1775      0    stevel 	/* Mark it as not confirmed. */
   1776      0    stevel 	fp->state = SCTP_FADDRS_UNCONFIRMED;
   1777      0    stevel 	fp->hb_interval = sctp->sctp_hb_interval;
   1778   3448  dh155122 	fp->ssthresh = sctps->sctps_initial_ssthresh;
   1779      0    stevel 	fp->suna = 0;
   1780      0    stevel 	fp->pba = 0;
   1781      0    stevel 	fp->acked = 0;
   1782  11066    rafael 	fp->lastactive = fp->hb_expiry = ddi_get_lbolt64();
   1783   1735    kcpoon 	fp->timer_mp = timer_mp;
   1784      0    stevel 	fp->hb_pending = B_FALSE;
   1785   4818    kcpoon 	fp->hb_enabled = B_TRUE;
   1786      0    stevel 	fp->df = 1;
   1787      0    stevel 	fp->pmtu_discovered = 0;
   1788      0    stevel 	fp->next = NULL;
   1789      0    stevel 	fp->T3expire = 0;
   1790      0    stevel 	(void) random_get_pseudo_bytes((uint8_t *)&fp->hb_secret,
   1791      0    stevel 	    sizeof (fp->hb_secret));
   1792   3795    kcpoon 	fp->rxt_unacked = 0;
   1793      0    stevel 
   1794  11042      Erik 	sctp_get_dest(sctp, fp);
   1795      0    stevel }
   1796      0    stevel 
   1797      0    stevel /*ARGSUSED*/
   1798   6712     tomee static int
   1799   6712     tomee faddr_constructor(void *buf, void *arg, int flags)
   1800   6712     tomee {
   1801   6712     tomee 	sctp_faddr_t *fp = buf;
   1802   6712     tomee 
   1803   6712     tomee 	fp->timer_mp = NULL;
   1804   6712     tomee 	fp->timer_running = 0;
   1805   6712     tomee 
   1806   6712     tomee 	fp->rc_timer_mp = NULL;
   1807   6712     tomee 	fp->rc_timer_running = 0;
   1808   6712     tomee 
   1809   6712     tomee 	return (0);
   1810   6712     tomee }
   1811   6712     tomee 
   1812   6712     tomee /*ARGSUSED*/
   1813      0    stevel static void
   1814   6712     tomee faddr_destructor(void *buf, void *arg)
   1815      0    stevel {
   1816      0    stevel 	sctp_faddr_t *fp = buf;
   1817      0    stevel 
   1818      0    stevel 	ASSERT(fp->timer_mp == NULL);
   1819      0    stevel 	ASSERT(fp->timer_running == 0);
   1820      0    stevel 
   1821      0    stevel 	ASSERT(fp->rc_timer_mp == NULL);
   1822      0    stevel 	ASSERT(fp->rc_timer_running == 0);
   1823      0    stevel }
   1824      0    stevel 
   1825      0    stevel void
   1826   1676       jpk sctp_faddr_init(void)
   1827      0    stevel {
   1828      0    stevel 	sctp_kmem_faddr_cache = kmem_cache_create("sctp_faddr_cache",
   1829   6712     tomee 	    sizeof (sctp_faddr_t), 0, faddr_constructor, faddr_destructor,
   1830      0    stevel 	    NULL, NULL, NULL, 0);
   1831      0    stevel }
   1832      0    stevel 
   1833      0    stevel void
   1834   1676       jpk sctp_faddr_fini(void)
   1835      0    stevel {
   1836      0    stevel 	kmem_cache_destroy(sctp_kmem_faddr_cache);
   1837      0    stevel }
   1838