The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/netinet/sctp_asconf.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 2001-2007, by Cisco Systems, Inc. All rights reserved.
    3  * Copyright (c) 2008-2012, by Randall Stewart. All rights reserved.
    4  * Copyright (c) 2008-2012, by Michael Tuexen. All rights reserved.
    5  *
    6  * Redistribution and use in source and binary forms, with or without
    7  * modification, are permitted provided that the following conditions are met:
    8  *
    9  * a) Redistributions of source code must retain the above copyright notice,
   10  *    this list of conditions and the following disclaimer.
   11  *
   12  * b) Redistributions in binary form must reproduce the above copyright
   13  *    notice, this list of conditions and the following disclaimer in
   14  *    the documentation and/or other materials provided with the distribution.
   15  *
   16  * c) Neither the name of Cisco Systems, Inc. nor the names of its
   17  *    contributors may be used to endorse or promote products derived
   18  *    from this software without specific prior written permission.
   19  *
   20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
   22  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   23  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
   24  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
   30  * THE POSSIBILITY OF SUCH DAMAGE.
   31  */
   32 
   33 #include <sys/cdefs.h>
   34 __FBSDID("$FreeBSD: releng/11.0/sys/netinet/sctp_asconf.c 298847 2016-04-30 14:25:00Z tuexen $");
   35 
   36 #include <netinet/sctp_os.h>
   37 #include <netinet/sctp_var.h>
   38 #include <netinet/sctp_sysctl.h>
   39 #include <netinet/sctp_pcb.h>
   40 #include <netinet/sctp_header.h>
   41 #include <netinet/sctputil.h>
   42 #include <netinet/sctp_output.h>
   43 #include <netinet/sctp_asconf.h>
   44 #include <netinet/sctp_timer.h>
   45 
   46 /*
   47  * debug flags:
   48  * SCTP_DEBUG_ASCONF1: protocol info, general info and errors
   49  * SCTP_DEBUG_ASCONF2: detailed info
   50  */
   51 
   52 
   53 /*
   54  * RFC 5061
   55  *
   56  * An ASCONF parameter queue exists per asoc which holds the pending address
   57  * operations.  Lists are updated upon receipt of ASCONF-ACK.
   58  *
   59  * A restricted_addrs list exists per assoc to hold local addresses that are
   60  * not (yet) usable by the assoc as a source address.  These addresses are
   61  * either pending an ASCONF operation (and exist on the ASCONF parameter
   62  * queue), or they are permanently restricted (the peer has returned an
   63  * ERROR indication to an ASCONF(ADD), or the peer does not support ASCONF).
   64  *
   65  * Deleted addresses are always immediately removed from the lists as they will
   66  * (shortly) no longer exist in the kernel.  We send ASCONFs as a courtesy,
   67  * only if allowed.
   68  */
   69 
   70 /*
   71  * ASCONF parameter processing.
   72  * response_required: set if a reply is required (eg. SUCCESS_REPORT).
   73  * returns a mbuf to an "error" response parameter or NULL/"success" if ok.
   74  * FIX: allocating this many mbufs on the fly is pretty inefficient...
   75  */
   76 static struct mbuf *
   77 sctp_asconf_success_response(uint32_t id)
   78 {
   79         struct mbuf *m_reply = NULL;
   80         struct sctp_asconf_paramhdr *aph;
   81 
   82         m_reply = sctp_get_mbuf_for_msg(sizeof(struct sctp_asconf_paramhdr),
   83             0, M_NOWAIT, 1, MT_DATA);
   84         if (m_reply == NULL) {
   85                 SCTPDBG(SCTP_DEBUG_ASCONF1,
   86                     "asconf_success_response: couldn't get mbuf!\n");
   87                 return (NULL);
   88         }
   89         aph = mtod(m_reply, struct sctp_asconf_paramhdr *);
   90         aph->correlation_id = id;
   91         aph->ph.param_type = htons(SCTP_SUCCESS_REPORT);
   92         aph->ph.param_length = sizeof(struct sctp_asconf_paramhdr);
   93         SCTP_BUF_LEN(m_reply) = aph->ph.param_length;
   94         aph->ph.param_length = htons(aph->ph.param_length);
   95 
   96         return (m_reply);
   97 }
   98 
   99 static struct mbuf *
  100 sctp_asconf_error_response(uint32_t id, uint16_t cause, uint8_t * error_tlv,
  101     uint16_t tlv_length)
  102 {
  103         struct mbuf *m_reply = NULL;
  104         struct sctp_asconf_paramhdr *aph;
  105         struct sctp_error_cause *error;
  106         uint8_t *tlv;
  107 
  108         m_reply = sctp_get_mbuf_for_msg((sizeof(struct sctp_asconf_paramhdr) +
  109             tlv_length +
  110             sizeof(struct sctp_error_cause)),
  111             0, M_NOWAIT, 1, MT_DATA);
  112         if (m_reply == NULL) {
  113                 SCTPDBG(SCTP_DEBUG_ASCONF1,
  114                     "asconf_error_response: couldn't get mbuf!\n");
  115                 return (NULL);
  116         }
  117         aph = mtod(m_reply, struct sctp_asconf_paramhdr *);
  118         error = (struct sctp_error_cause *)(aph + 1);
  119 
  120         aph->correlation_id = id;
  121         aph->ph.param_type = htons(SCTP_ERROR_CAUSE_IND);
  122         error->code = htons(cause);
  123         error->length = tlv_length + sizeof(struct sctp_error_cause);
  124         aph->ph.param_length = error->length +
  125             sizeof(struct sctp_asconf_paramhdr);
  126 
  127         if (aph->ph.param_length > MLEN) {
  128                 SCTPDBG(SCTP_DEBUG_ASCONF1,
  129                     "asconf_error_response: tlv_length (%xh) too big\n",
  130                     tlv_length);
  131                 sctp_m_freem(m_reply);  /* discard */
  132                 return (NULL);
  133         }
  134         if (error_tlv != NULL) {
  135                 tlv = (uint8_t *) (error + 1);
  136                 memcpy(tlv, error_tlv, tlv_length);
  137         }
  138         SCTP_BUF_LEN(m_reply) = aph->ph.param_length;
  139         error->length = htons(error->length);
  140         aph->ph.param_length = htons(aph->ph.param_length);
  141 
  142         return (m_reply);
  143 }
  144 
  145 static struct mbuf *
  146 sctp_process_asconf_add_ip(struct sockaddr *src, struct sctp_asconf_paramhdr *aph,
  147     struct sctp_tcb *stcb, int send_hb, int response_required)
  148 {
  149         struct sctp_nets *net;
  150         struct mbuf *m_reply = NULL;
  151         union sctp_sockstore store;
  152         struct sctp_paramhdr *ph;
  153         uint16_t param_type, aparam_length;
  154 
  155 #if defined(INET) || defined(INET6)
  156         uint16_t param_length;
  157 
  158 #endif
  159         struct sockaddr *sa;
  160         int zero_address = 0;
  161         int bad_address = 0;
  162 
  163 #ifdef INET
  164         struct sockaddr_in *sin;
  165         struct sctp_ipv4addr_param *v4addr;
  166 
  167 #endif
  168 #ifdef INET6
  169         struct sockaddr_in6 *sin6;
  170         struct sctp_ipv6addr_param *v6addr;
  171 
  172 #endif
  173 
  174         aparam_length = ntohs(aph->ph.param_length);
  175         ph = (struct sctp_paramhdr *)(aph + 1);
  176         param_type = ntohs(ph->param_type);
  177 #if defined(INET) || defined(INET6)
  178         param_length = ntohs(ph->param_length);
  179 #endif
  180         sa = &store.sa;
  181         switch (param_type) {
  182 #ifdef INET
  183         case SCTP_IPV4_ADDRESS:
  184                 if (param_length != sizeof(struct sctp_ipv4addr_param)) {
  185                         /* invalid param size */
  186                         return (NULL);
  187                 }
  188                 v4addr = (struct sctp_ipv4addr_param *)ph;
  189                 sin = &store.sin;
  190                 bzero(sin, sizeof(*sin));
  191                 sin->sin_family = AF_INET;
  192                 sin->sin_len = sizeof(struct sockaddr_in);
  193                 sin->sin_port = stcb->rport;
  194                 sin->sin_addr.s_addr = v4addr->addr;
  195                 if ((sin->sin_addr.s_addr == INADDR_BROADCAST) ||
  196                     IN_MULTICAST(ntohl(sin->sin_addr.s_addr))) {
  197                         bad_address = 1;
  198                 }
  199                 if (sin->sin_addr.s_addr == INADDR_ANY)
  200                         zero_address = 1;
  201                 SCTPDBG(SCTP_DEBUG_ASCONF1, "process_asconf_add_ip: adding ");
  202                 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
  203                 break;
  204 #endif
  205 #ifdef INET6
  206         case SCTP_IPV6_ADDRESS:
  207                 if (param_length != sizeof(struct sctp_ipv6addr_param)) {
  208                         /* invalid param size */
  209                         return (NULL);
  210                 }
  211                 v6addr = (struct sctp_ipv6addr_param *)ph;
  212                 sin6 = &store.sin6;
  213                 bzero(sin6, sizeof(*sin6));
  214                 sin6->sin6_family = AF_INET6;
  215                 sin6->sin6_len = sizeof(struct sockaddr_in6);
  216                 sin6->sin6_port = stcb->rport;
  217                 memcpy((caddr_t)&sin6->sin6_addr, v6addr->addr,
  218                     sizeof(struct in6_addr));
  219                 if (IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)) {
  220                         bad_address = 1;
  221                 }
  222                 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr))
  223                         zero_address = 1;
  224                 SCTPDBG(SCTP_DEBUG_ASCONF1, "process_asconf_add_ip: adding ");
  225                 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
  226                 break;
  227 #endif
  228         default:
  229                 m_reply = sctp_asconf_error_response(aph->correlation_id,
  230                     SCTP_CAUSE_INVALID_PARAM, (uint8_t *) aph,
  231                     aparam_length);
  232                 return (m_reply);
  233         }                       /* end switch */
  234 
  235         /* if 0.0.0.0/::0, add the source address instead */
  236         if (zero_address && SCTP_BASE_SYSCTL(sctp_nat_friendly)) {
  237                 sa = src;
  238                 SCTPDBG(SCTP_DEBUG_ASCONF1,
  239                     "process_asconf_add_ip: using source addr ");
  240                 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, src);
  241         }
  242         /* add the address */
  243         if (bad_address) {
  244                 m_reply = sctp_asconf_error_response(aph->correlation_id,
  245                     SCTP_CAUSE_INVALID_PARAM, (uint8_t *) aph,
  246                     aparam_length);
  247         } else if (sctp_add_remote_addr(stcb, sa, &net, stcb->asoc.port,
  248                     SCTP_DONOT_SETSCOPE,
  249             SCTP_ADDR_DYNAMIC_ADDED) != 0) {
  250                 SCTPDBG(SCTP_DEBUG_ASCONF1,
  251                     "process_asconf_add_ip: error adding address\n");
  252                 m_reply = sctp_asconf_error_response(aph->correlation_id,
  253                     SCTP_CAUSE_RESOURCE_SHORTAGE, (uint8_t *) aph,
  254                     aparam_length);
  255         } else {
  256                 /* notify upper layer */
  257                 sctp_ulp_notify(SCTP_NOTIFY_ASCONF_ADD_IP, stcb, 0, sa, SCTP_SO_NOT_LOCKED);
  258                 if (response_required) {
  259                         m_reply =
  260                             sctp_asconf_success_response(aph->correlation_id);
  261                 }
  262                 sctp_timer_start(SCTP_TIMER_TYPE_PATHMTURAISE, stcb->sctp_ep, stcb, net);
  263                 sctp_timer_start(SCTP_TIMER_TYPE_HEARTBEAT, stcb->sctp_ep,
  264                     stcb, net);
  265                 if (send_hb) {
  266                         sctp_send_hb(stcb, net, SCTP_SO_NOT_LOCKED);
  267                 }
  268         }
  269         return (m_reply);
  270 }
  271 
  272 static int
  273 sctp_asconf_del_remote_addrs_except(struct sctp_tcb *stcb, struct sockaddr *src)
  274 {
  275         struct sctp_nets *src_net, *net;
  276 
  277         /* make sure the source address exists as a destination net */
  278         src_net = sctp_findnet(stcb, src);
  279         if (src_net == NULL) {
  280                 /* not found */
  281                 return (-1);
  282         }
  283         /* delete all destination addresses except the source */
  284         TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
  285                 if (net != src_net) {
  286                         /* delete this address */
  287                         sctp_remove_net(stcb, net);
  288                         SCTPDBG(SCTP_DEBUG_ASCONF1,
  289                             "asconf_del_remote_addrs_except: deleting ");
  290                         SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1,
  291                             (struct sockaddr *)&net->ro._l_addr);
  292                         /* notify upper layer */
  293                         sctp_ulp_notify(SCTP_NOTIFY_ASCONF_DELETE_IP, stcb, 0,
  294                             (struct sockaddr *)&net->ro._l_addr, SCTP_SO_NOT_LOCKED);
  295                 }
  296         }
  297         return (0);
  298 }
  299 
  300 static struct mbuf *
  301 sctp_process_asconf_delete_ip(struct sockaddr *src,
  302     struct sctp_asconf_paramhdr *aph,
  303     struct sctp_tcb *stcb, int response_required)
  304 {
  305         struct mbuf *m_reply = NULL;
  306         union sctp_sockstore store;
  307         struct sctp_paramhdr *ph;
  308         uint16_t param_type, aparam_length;
  309 
  310 #if defined(INET) || defined(INET6)
  311         uint16_t param_length;
  312 
  313 #endif
  314         struct sockaddr *sa;
  315         int zero_address = 0;
  316         int result;
  317 
  318 #ifdef INET
  319         struct sockaddr_in *sin;
  320         struct sctp_ipv4addr_param *v4addr;
  321 
  322 #endif
  323 #ifdef INET6
  324         struct sockaddr_in6 *sin6;
  325         struct sctp_ipv6addr_param *v6addr;
  326 
  327 #endif
  328 
  329         aparam_length = ntohs(aph->ph.param_length);
  330         ph = (struct sctp_paramhdr *)(aph + 1);
  331         param_type = ntohs(ph->param_type);
  332 #if defined(INET) || defined(INET6)
  333         param_length = ntohs(ph->param_length);
  334 #endif
  335         sa = &store.sa;
  336         switch (param_type) {
  337 #ifdef INET
  338         case SCTP_IPV4_ADDRESS:
  339                 if (param_length != sizeof(struct sctp_ipv4addr_param)) {
  340                         /* invalid param size */
  341                         return (NULL);
  342                 }
  343                 v4addr = (struct sctp_ipv4addr_param *)ph;
  344                 sin = &store.sin;
  345                 bzero(sin, sizeof(*sin));
  346                 sin->sin_family = AF_INET;
  347                 sin->sin_len = sizeof(struct sockaddr_in);
  348                 sin->sin_port = stcb->rport;
  349                 sin->sin_addr.s_addr = v4addr->addr;
  350                 if (sin->sin_addr.s_addr == INADDR_ANY)
  351                         zero_address = 1;
  352                 SCTPDBG(SCTP_DEBUG_ASCONF1,
  353                     "process_asconf_delete_ip: deleting ");
  354                 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
  355                 break;
  356 #endif
  357 #ifdef INET6
  358         case SCTP_IPV6_ADDRESS:
  359                 if (param_length != sizeof(struct sctp_ipv6addr_param)) {
  360                         /* invalid param size */
  361                         return (NULL);
  362                 }
  363                 v6addr = (struct sctp_ipv6addr_param *)ph;
  364                 sin6 = &store.sin6;
  365                 bzero(sin6, sizeof(*sin6));
  366                 sin6->sin6_family = AF_INET6;
  367                 sin6->sin6_len = sizeof(struct sockaddr_in6);
  368                 sin6->sin6_port = stcb->rport;
  369                 memcpy(&sin6->sin6_addr, v6addr->addr,
  370                     sizeof(struct in6_addr));
  371                 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr))
  372                         zero_address = 1;
  373                 SCTPDBG(SCTP_DEBUG_ASCONF1,
  374                     "process_asconf_delete_ip: deleting ");
  375                 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
  376                 break;
  377 #endif
  378         default:
  379                 m_reply = sctp_asconf_error_response(aph->correlation_id,
  380                     SCTP_CAUSE_UNRESOLVABLE_ADDR, (uint8_t *) aph,
  381                     aparam_length);
  382                 return (m_reply);
  383         }
  384 
  385         /* make sure the source address is not being deleted */
  386         if (sctp_cmpaddr(sa, src)) {
  387                 /* trying to delete the source address! */
  388                 SCTPDBG(SCTP_DEBUG_ASCONF1, "process_asconf_delete_ip: tried to delete source addr\n");
  389                 m_reply = sctp_asconf_error_response(aph->correlation_id,
  390                     SCTP_CAUSE_DELETING_SRC_ADDR, (uint8_t *) aph,
  391                     aparam_length);
  392                 return (m_reply);
  393         }
  394         /* if deleting 0.0.0.0/::0, delete all addresses except src addr */
  395         if (zero_address && SCTP_BASE_SYSCTL(sctp_nat_friendly)) {
  396                 result = sctp_asconf_del_remote_addrs_except(stcb, src);
  397 
  398                 if (result) {
  399                         /* src address did not exist? */
  400                         SCTPDBG(SCTP_DEBUG_ASCONF1, "process_asconf_delete_ip: src addr does not exist?\n");
  401                         /* what error to reply with?? */
  402                         m_reply =
  403                             sctp_asconf_error_response(aph->correlation_id,
  404                             SCTP_CAUSE_REQUEST_REFUSED, (uint8_t *) aph,
  405                             aparam_length);
  406                 } else if (response_required) {
  407                         m_reply =
  408                             sctp_asconf_success_response(aph->correlation_id);
  409                 }
  410                 return (m_reply);
  411         }
  412         /* delete the address */
  413         result = sctp_del_remote_addr(stcb, sa);
  414         /*
  415          * note if result == -2, the address doesn't exist in the asoc but
  416          * since it's being deleted anyways, we just ack the delete -- but
  417          * this probably means something has already gone awry
  418          */
  419         if (result == -1) {
  420                 /* only one address in the asoc */
  421                 SCTPDBG(SCTP_DEBUG_ASCONF1, "process_asconf_delete_ip: tried to delete last IP addr!\n");
  422                 m_reply = sctp_asconf_error_response(aph->correlation_id,
  423                     SCTP_CAUSE_DELETING_LAST_ADDR, (uint8_t *) aph,
  424                     aparam_length);
  425         } else {
  426                 if (response_required) {
  427                         m_reply = sctp_asconf_success_response(aph->correlation_id);
  428                 }
  429                 /* notify upper layer */
  430                 sctp_ulp_notify(SCTP_NOTIFY_ASCONF_DELETE_IP, stcb, 0, sa, SCTP_SO_NOT_LOCKED);
  431         }
  432         return (m_reply);
  433 }
  434 
  435 static struct mbuf *
  436 sctp_process_asconf_set_primary(struct sockaddr *src,
  437     struct sctp_asconf_paramhdr *aph,
  438     struct sctp_tcb *stcb, int response_required)
  439 {
  440         struct mbuf *m_reply = NULL;
  441         union sctp_sockstore store;
  442         struct sctp_paramhdr *ph;
  443         uint16_t param_type, aparam_length;
  444 
  445 #if defined(INET) || defined(INET6)
  446         uint16_t param_length;
  447 
  448 #endif
  449         struct sockaddr *sa;
  450         int zero_address = 0;
  451 
  452 #ifdef INET
  453         struct sockaddr_in *sin;
  454         struct sctp_ipv4addr_param *v4addr;
  455 
  456 #endif
  457 #ifdef INET6
  458         struct sockaddr_in6 *sin6;
  459         struct sctp_ipv6addr_param *v6addr;
  460 
  461 #endif
  462 
  463         aparam_length = ntohs(aph->ph.param_length);
  464         ph = (struct sctp_paramhdr *)(aph + 1);
  465         param_type = ntohs(ph->param_type);
  466 #if defined(INET) || defined(INET6)
  467         param_length = ntohs(ph->param_length);
  468 #endif
  469         sa = &store.sa;
  470         switch (param_type) {
  471 #ifdef INET
  472         case SCTP_IPV4_ADDRESS:
  473                 if (param_length != sizeof(struct sctp_ipv4addr_param)) {
  474                         /* invalid param size */
  475                         return (NULL);
  476                 }
  477                 v4addr = (struct sctp_ipv4addr_param *)ph;
  478                 sin = &store.sin;
  479                 bzero(sin, sizeof(*sin));
  480                 sin->sin_family = AF_INET;
  481                 sin->sin_len = sizeof(struct sockaddr_in);
  482                 sin->sin_addr.s_addr = v4addr->addr;
  483                 if (sin->sin_addr.s_addr == INADDR_ANY)
  484                         zero_address = 1;
  485                 SCTPDBG(SCTP_DEBUG_ASCONF1, "process_asconf_set_primary: ");
  486                 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
  487                 break;
  488 #endif
  489 #ifdef INET6
  490         case SCTP_IPV6_ADDRESS:
  491                 if (param_length != sizeof(struct sctp_ipv6addr_param)) {
  492                         /* invalid param size */
  493                         return (NULL);
  494                 }
  495                 v6addr = (struct sctp_ipv6addr_param *)ph;
  496                 sin6 = &store.sin6;
  497                 bzero(sin6, sizeof(*sin6));
  498                 sin6->sin6_family = AF_INET6;
  499                 sin6->sin6_len = sizeof(struct sockaddr_in6);
  500                 memcpy((caddr_t)&sin6->sin6_addr, v6addr->addr,
  501                     sizeof(struct in6_addr));
  502                 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr))
  503                         zero_address = 1;
  504                 SCTPDBG(SCTP_DEBUG_ASCONF1, "process_asconf_set_primary: ");
  505                 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
  506                 break;
  507 #endif
  508         default:
  509                 m_reply = sctp_asconf_error_response(aph->correlation_id,
  510                     SCTP_CAUSE_UNRESOLVABLE_ADDR, (uint8_t *) aph,
  511                     aparam_length);
  512                 return (m_reply);
  513         }
  514 
  515         /* if 0.0.0.0/::0, use the source address instead */
  516         if (zero_address && SCTP_BASE_SYSCTL(sctp_nat_friendly)) {
  517                 sa = src;
  518                 SCTPDBG(SCTP_DEBUG_ASCONF1,
  519                     "process_asconf_set_primary: using source addr ");
  520                 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, src);
  521         }
  522         /* set the primary address */
  523         if (sctp_set_primary_addr(stcb, sa, NULL) == 0) {
  524                 SCTPDBG(SCTP_DEBUG_ASCONF1,
  525                     "process_asconf_set_primary: primary address set\n");
  526                 /* notify upper layer */
  527                 sctp_ulp_notify(SCTP_NOTIFY_ASCONF_SET_PRIMARY, stcb, 0, sa, SCTP_SO_NOT_LOCKED);
  528                 if ((stcb->asoc.primary_destination->dest_state & SCTP_ADDR_REACHABLE) &&
  529                     (!(stcb->asoc.primary_destination->dest_state & SCTP_ADDR_PF)) &&
  530                     (stcb->asoc.alternate)) {
  531                         sctp_free_remote_addr(stcb->asoc.alternate);
  532                         stcb->asoc.alternate = NULL;
  533                 }
  534                 if (response_required) {
  535                         m_reply = sctp_asconf_success_response(aph->correlation_id);
  536                 }
  537                 /*
  538                  * Mobility adaptation. Ideally, when the reception of SET
  539                  * PRIMARY with DELETE IP ADDRESS of the previous primary
  540                  * destination, unacknowledged DATA are retransmitted
  541                  * immediately to the new primary destination for seamless
  542                  * handover. If the destination is UNCONFIRMED and marked to
  543                  * REQ_PRIM, The retransmission occur when reception of the
  544                  * HEARTBEAT-ACK.  (See sctp_handle_heartbeat_ack in
  545                  * sctp_input.c) Also, when change of the primary
  546                  * destination, it is better that all subsequent new DATA
  547                  * containing already queued DATA are transmitted to the new
  548                  * primary destination. (by micchie)
  549                  */
  550                 if ((sctp_is_mobility_feature_on(stcb->sctp_ep,
  551                     SCTP_MOBILITY_BASE) ||
  552                     sctp_is_mobility_feature_on(stcb->sctp_ep,
  553                     SCTP_MOBILITY_FASTHANDOFF)) &&
  554                     sctp_is_mobility_feature_on(stcb->sctp_ep,
  555                     SCTP_MOBILITY_PRIM_DELETED) &&
  556                     (stcb->asoc.primary_destination->dest_state &
  557                     SCTP_ADDR_UNCONFIRMED) == 0) {
  558 
  559                         sctp_timer_stop(SCTP_TIMER_TYPE_PRIM_DELETED,
  560                             stcb->sctp_ep, stcb, NULL,
  561                             SCTP_FROM_SCTP_ASCONF + SCTP_LOC_1);
  562                         if (sctp_is_mobility_feature_on(stcb->sctp_ep,
  563                             SCTP_MOBILITY_FASTHANDOFF)) {
  564                                 sctp_assoc_immediate_retrans(stcb,
  565                                     stcb->asoc.primary_destination);
  566                         }
  567                         if (sctp_is_mobility_feature_on(stcb->sctp_ep,
  568                             SCTP_MOBILITY_BASE)) {
  569                                 sctp_move_chunks_from_net(stcb,
  570                                     stcb->asoc.deleted_primary);
  571                         }
  572                         sctp_delete_prim_timer(stcb->sctp_ep, stcb,
  573                             stcb->asoc.deleted_primary);
  574                 }
  575         } else {
  576                 /* couldn't set the requested primary address! */
  577                 SCTPDBG(SCTP_DEBUG_ASCONF1,
  578                     "process_asconf_set_primary: set primary failed!\n");
  579                 /* must have been an invalid address, so report */
  580                 m_reply = sctp_asconf_error_response(aph->correlation_id,
  581                     SCTP_CAUSE_UNRESOLVABLE_ADDR, (uint8_t *) aph,
  582                     aparam_length);
  583         }
  584 
  585         return (m_reply);
  586 }
  587 
  588 /*
  589  * handles an ASCONF chunk.
  590  * if all parameters are processed ok, send a plain (empty) ASCONF-ACK
  591  */
  592 void
  593 sctp_handle_asconf(struct mbuf *m, unsigned int offset,
  594     struct sockaddr *src,
  595     struct sctp_asconf_chunk *cp, struct sctp_tcb *stcb,
  596     int first)
  597 {
  598         struct sctp_association *asoc;
  599         uint32_t serial_num;
  600         struct mbuf *n, *m_ack, *m_result, *m_tail;
  601         struct sctp_asconf_ack_chunk *ack_cp;
  602         struct sctp_asconf_paramhdr *aph;
  603         struct sctp_ipv6addr_param *p_addr;
  604         unsigned int asconf_limit, cnt;
  605         int error = 0;          /* did an error occur? */
  606 
  607         /* asconf param buffer */
  608         uint8_t aparam_buf[SCTP_PARAM_BUFFER_SIZE];
  609         struct sctp_asconf_ack *ack, *ack_next;
  610 
  611         /* verify minimum length */
  612         if (ntohs(cp->ch.chunk_length) < sizeof(struct sctp_asconf_chunk)) {
  613                 SCTPDBG(SCTP_DEBUG_ASCONF1,
  614                     "handle_asconf: chunk too small = %xh\n",
  615                     ntohs(cp->ch.chunk_length));
  616                 return;
  617         }
  618         asoc = &stcb->asoc;
  619         serial_num = ntohl(cp->serial_number);
  620 
  621         if (SCTP_TSN_GE(asoc->asconf_seq_in, serial_num)) {
  622                 /* got a duplicate ASCONF */
  623                 SCTPDBG(SCTP_DEBUG_ASCONF1,
  624                     "handle_asconf: got duplicate serial number = %xh\n",
  625                     serial_num);
  626                 return;
  627         } else if (serial_num != (asoc->asconf_seq_in + 1)) {
  628                 SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf: incorrect serial number = %xh (expected next = %xh)\n",
  629                     serial_num, asoc->asconf_seq_in + 1);
  630                 return;
  631         }
  632         /* it's the expected "next" sequence number, so process it */
  633         asoc->asconf_seq_in = serial_num;       /* update sequence */
  634         /* get length of all the param's in the ASCONF */
  635         asconf_limit = offset + ntohs(cp->ch.chunk_length);
  636         SCTPDBG(SCTP_DEBUG_ASCONF1,
  637             "handle_asconf: asconf_limit=%u, sequence=%xh\n",
  638             asconf_limit, serial_num);
  639 
  640         if (first) {
  641                 /* delete old cache */
  642                 SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf: Now processing first ASCONF. Try to delete old cache\n");
  643 
  644                 TAILQ_FOREACH_SAFE(ack, &asoc->asconf_ack_sent, next, ack_next) {
  645                         if (ack->serial_number == serial_num)
  646                                 break;
  647                         SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf: delete old(%u) < first(%u)\n",
  648                             ack->serial_number, serial_num);
  649                         TAILQ_REMOVE(&asoc->asconf_ack_sent, ack, next);
  650                         if (ack->data != NULL) {
  651                                 sctp_m_freem(ack->data);
  652                         }
  653                         SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_asconf_ack), ack);
  654                 }
  655         }
  656         m_ack = sctp_get_mbuf_for_msg(sizeof(struct sctp_asconf_ack_chunk), 0,
  657             M_NOWAIT, 1, MT_DATA);
  658         if (m_ack == NULL) {
  659                 SCTPDBG(SCTP_DEBUG_ASCONF1,
  660                     "handle_asconf: couldn't get mbuf!\n");
  661                 return;
  662         }
  663         m_tail = m_ack;         /* current reply chain's tail */
  664 
  665         /* fill in ASCONF-ACK header */
  666         ack_cp = mtod(m_ack, struct sctp_asconf_ack_chunk *);
  667         ack_cp->ch.chunk_type = SCTP_ASCONF_ACK;
  668         ack_cp->ch.chunk_flags = 0;
  669         ack_cp->serial_number = htonl(serial_num);
  670         /* set initial lengths (eg. just an ASCONF-ACK), ntohx at the end! */
  671         SCTP_BUF_LEN(m_ack) = sizeof(struct sctp_asconf_ack_chunk);
  672         ack_cp->ch.chunk_length = sizeof(struct sctp_asconf_ack_chunk);
  673 
  674         /* skip the lookup address parameter */
  675         offset += sizeof(struct sctp_asconf_chunk);
  676         p_addr = (struct sctp_ipv6addr_param *)sctp_m_getptr(m, offset, sizeof(struct sctp_paramhdr), (uint8_t *) & aparam_buf);
  677         if (p_addr == NULL) {
  678                 SCTPDBG(SCTP_DEBUG_ASCONF1,
  679                     "handle_asconf: couldn't get lookup addr!\n");
  680                 /* respond with a missing/invalid mandatory parameter error */
  681                 return;
  682         }
  683         /* param_length is already validated in process_control... */
  684         offset += ntohs(p_addr->ph.param_length);       /* skip lookup addr */
  685         /* get pointer to first asconf param in ASCONF */
  686         aph = (struct sctp_asconf_paramhdr *)sctp_m_getptr(m, offset, sizeof(struct sctp_asconf_paramhdr), (uint8_t *) & aparam_buf);
  687         if (aph == NULL) {
  688                 SCTPDBG(SCTP_DEBUG_ASCONF1, "Empty ASCONF received?\n");
  689                 goto send_reply;
  690         }
  691         /* process through all parameters */
  692         cnt = 0;
  693         while (aph != NULL) {
  694                 unsigned int param_length, param_type;
  695 
  696                 param_type = ntohs(aph->ph.param_type);
  697                 param_length = ntohs(aph->ph.param_length);
  698                 if (offset + param_length > asconf_limit) {
  699                         /* parameter goes beyond end of chunk! */
  700                         sctp_m_freem(m_ack);
  701                         return;
  702                 }
  703                 m_result = NULL;
  704 
  705                 if (param_length > sizeof(aparam_buf)) {
  706                         SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf: param length (%u) larger than buffer size!\n", param_length);
  707                         sctp_m_freem(m_ack);
  708                         return;
  709                 }
  710                 if (param_length <= sizeof(struct sctp_paramhdr)) {
  711                         SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf: param length (%u) too short\n", param_length);
  712                         sctp_m_freem(m_ack);
  713                 }
  714                 /* get the entire parameter */
  715                 aph = (struct sctp_asconf_paramhdr *)sctp_m_getptr(m, offset, param_length, aparam_buf);
  716                 if (aph == NULL) {
  717                         SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf: couldn't get entire param\n");
  718                         sctp_m_freem(m_ack);
  719                         return;
  720                 }
  721                 switch (param_type) {
  722                 case SCTP_ADD_IP_ADDRESS:
  723                         m_result = sctp_process_asconf_add_ip(src, aph, stcb,
  724                             (cnt < SCTP_BASE_SYSCTL(sctp_hb_maxburst)), error);
  725                         cnt++;
  726                         break;
  727                 case SCTP_DEL_IP_ADDRESS:
  728                         m_result = sctp_process_asconf_delete_ip(src, aph, stcb,
  729                             error);
  730                         break;
  731                 case SCTP_ERROR_CAUSE_IND:
  732                         /* not valid in an ASCONF chunk */
  733                         break;
  734                 case SCTP_SET_PRIM_ADDR:
  735                         m_result = sctp_process_asconf_set_primary(src, aph,
  736                             stcb, error);
  737                         break;
  738                 case SCTP_NAT_VTAGS:
  739                         SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf: sees a NAT VTAG state parameter\n");
  740                         break;
  741                 case SCTP_SUCCESS_REPORT:
  742                         /* not valid in an ASCONF chunk */
  743                         break;
  744                 case SCTP_ULP_ADAPTATION:
  745                         /* FIX */
  746                         break;
  747                 default:
  748                         if ((param_type & 0x8000) == 0) {
  749                                 /* Been told to STOP at this param */
  750                                 asconf_limit = offset;
  751                                 /*
  752                                  * FIX FIX - We need to call
  753                                  * sctp_arethere_unrecognized_parameters()
  754                                  * to get a operr and send it for any
  755                                  * param's with the 0x4000 bit set OR do it
  756                                  * here ourselves... note we still must STOP
  757                                  * if the 0x8000 bit is clear.
  758                                  */
  759                         }
  760                         /* unknown/invalid param type */
  761                         break;
  762                 }               /* switch */
  763 
  764                 /* add any (error) result to the reply mbuf chain */
  765                 if (m_result != NULL) {
  766                         SCTP_BUF_NEXT(m_tail) = m_result;
  767                         m_tail = m_result;
  768                         /* update lengths, make sure it's aligned too */
  769                         SCTP_BUF_LEN(m_result) = SCTP_SIZE32(SCTP_BUF_LEN(m_result));
  770                         ack_cp->ch.chunk_length += SCTP_BUF_LEN(m_result);
  771                         /* set flag to force success reports */
  772                         error = 1;
  773                 }
  774                 offset += SCTP_SIZE32(param_length);
  775                 /* update remaining ASCONF message length to process */
  776                 if (offset >= asconf_limit) {
  777                         /* no more data in the mbuf chain */
  778                         break;
  779                 }
  780                 /* get pointer to next asconf param */
  781                 aph = (struct sctp_asconf_paramhdr *)sctp_m_getptr(m, offset,
  782                     sizeof(struct sctp_asconf_paramhdr),
  783                     (uint8_t *) & aparam_buf);
  784                 if (aph == NULL) {
  785                         /* can't get an asconf paramhdr */
  786                         SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf: can't get asconf param hdr!\n");
  787                         /* FIX ME - add error here... */
  788                 }
  789         }
  790 
  791 send_reply:
  792         ack_cp->ch.chunk_length = htons(ack_cp->ch.chunk_length);
  793         /* save the ASCONF-ACK reply */
  794         ack = SCTP_ZONE_GET(SCTP_BASE_INFO(ipi_zone_asconf_ack),
  795             struct sctp_asconf_ack);
  796         if (ack == NULL) {
  797                 sctp_m_freem(m_ack);
  798                 return;
  799         }
  800         ack->serial_number = serial_num;
  801         ack->last_sent_to = NULL;
  802         ack->data = m_ack;
  803         ack->len = 0;
  804         for (n = m_ack; n != NULL; n = SCTP_BUF_NEXT(n)) {
  805                 ack->len += SCTP_BUF_LEN(n);
  806         }
  807         TAILQ_INSERT_TAIL(&stcb->asoc.asconf_ack_sent, ack, next);
  808 
  809         /* see if last_control_chunk_from is set properly (use IP src addr) */
  810         if (stcb->asoc.last_control_chunk_from == NULL) {
  811                 /*
  812                  * this could happen if the source address was just newly
  813                  * added
  814                  */
  815                 SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf: looking up net for IP source address\n");
  816                 SCTPDBG(SCTP_DEBUG_ASCONF1, "Looking for IP source: ");
  817                 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, src);
  818                 /* look up the from address */
  819                 stcb->asoc.last_control_chunk_from = sctp_findnet(stcb, src);
  820 #ifdef SCTP_DEBUG
  821                 if (stcb->asoc.last_control_chunk_from == NULL) {
  822                         SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf: IP source address not found?!\n");
  823                 }
  824 #endif
  825         }
  826 }
  827 
  828 /*
  829  * does the address match? returns 0 if not, 1 if so
  830  */
  831 static uint32_t
  832 sctp_asconf_addr_match(struct sctp_asconf_addr *aa, struct sockaddr *sa)
  833 {
  834         switch (sa->sa_family) {
  835 #ifdef INET6
  836         case AF_INET6:
  837                 {
  838                         /* XXX scopeid */
  839                         struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
  840 
  841                         if ((aa->ap.addrp.ph.param_type == SCTP_IPV6_ADDRESS) &&
  842                             (memcmp(&aa->ap.addrp.addr, &sin6->sin6_addr,
  843                             sizeof(struct in6_addr)) == 0)) {
  844                                 return (1);
  845                         }
  846                         break;
  847                 }
  848 #endif
  849 #ifdef INET
  850         case AF_INET:
  851                 {
  852                         struct sockaddr_in *sin = (struct sockaddr_in *)sa;
  853 
  854                         if ((aa->ap.addrp.ph.param_type == SCTP_IPV4_ADDRESS) &&
  855                             (memcmp(&aa->ap.addrp.addr, &sin->sin_addr,
  856                             sizeof(struct in_addr)) == 0)) {
  857                                 return (1);
  858                         }
  859                         break;
  860                 }
  861 #endif
  862         default:
  863                 break;
  864         }
  865         return (0);
  866 }
  867 
  868 /*
  869  * does the address match? returns 0 if not, 1 if so
  870  */
  871 static uint32_t
  872 sctp_addr_match(struct sctp_paramhdr *ph, struct sockaddr *sa)
  873 {
  874 #if defined(INET) || defined(INET6)
  875         uint16_t param_type, param_length;
  876 
  877         param_type = ntohs(ph->param_type);
  878         param_length = ntohs(ph->param_length);
  879 #endif
  880         switch (sa->sa_family) {
  881 #ifdef INET6
  882         case AF_INET6:
  883                 {
  884                         /* XXX scopeid */
  885                         struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
  886                         struct sctp_ipv6addr_param *v6addr;
  887 
  888                         v6addr = (struct sctp_ipv6addr_param *)ph;
  889                         if ((param_type == SCTP_IPV6_ADDRESS) &&
  890                             (param_length == sizeof(struct sctp_ipv6addr_param)) &&
  891                             (memcmp(&v6addr->addr, &sin6->sin6_addr,
  892                             sizeof(struct in6_addr)) == 0)) {
  893                                 return (1);
  894                         }
  895                         break;
  896                 }
  897 #endif
  898 #ifdef INET
  899         case AF_INET:
  900                 {
  901                         struct sockaddr_in *sin = (struct sockaddr_in *)sa;
  902                         struct sctp_ipv4addr_param *v4addr;
  903 
  904                         v4addr = (struct sctp_ipv4addr_param *)ph;
  905                         if ((param_type == SCTP_IPV4_ADDRESS) &&
  906                             (param_length == sizeof(struct sctp_ipv4addr_param)) &&
  907                             (memcmp(&v4addr->addr, &sin->sin_addr,
  908                             sizeof(struct in_addr)) == 0)) {
  909                                 return (1);
  910                         }
  911                         break;
  912                 }
  913 #endif
  914         default:
  915                 break;
  916         }
  917         return (0);
  918 }
  919 
  920 /*
  921  * Cleanup for non-responded/OP ERR'd ASCONF
  922  */
  923 void
  924 sctp_asconf_cleanup(struct sctp_tcb *stcb, struct sctp_nets *net)
  925 {
  926         /*
  927          * clear out any existing asconfs going out
  928          */
  929         sctp_timer_stop(SCTP_TIMER_TYPE_ASCONF, stcb->sctp_ep, stcb, net,
  930             SCTP_FROM_SCTP_ASCONF + SCTP_LOC_2);
  931         stcb->asoc.asconf_seq_out_acked = stcb->asoc.asconf_seq_out;
  932         /* remove the old ASCONF on our outbound queue */
  933         sctp_toss_old_asconf(stcb);
  934 }
  935 
  936 /*
  937  * cleanup any cached source addresses that may be topologically
  938  * incorrect after a new address has been added to this interface.
  939  */
  940 static void
  941 sctp_asconf_nets_cleanup(struct sctp_tcb *stcb, struct sctp_ifn *ifn)
  942 {
  943         struct sctp_nets *net;
  944 
  945         /*
  946          * Ideally, we want to only clear cached routes and source addresses
  947          * that are topologically incorrect.  But since there is no easy way
  948          * to know whether the newly added address on the ifn would cause a
  949          * routing change (i.e. a new egress interface would be chosen)
  950          * without doing a new routing lookup and source address selection,
  951          * we will (for now) just flush any cached route using a different
  952          * ifn (and cached source addrs) and let output re-choose them
  953          * during the next send on that net.
  954          */
  955         TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
  956                 /*
  957                  * clear any cached route (and cached source address) if the
  958                  * route's interface is NOT the same as the address change.
  959                  * If it's the same interface, just clear the cached source
  960                  * address.
  961                  */
  962                 if (SCTP_ROUTE_HAS_VALID_IFN(&net->ro) &&
  963                     ((ifn == NULL) ||
  964                     (SCTP_GET_IF_INDEX_FROM_ROUTE(&net->ro) != ifn->ifn_index))) {
  965                         /* clear any cached route */
  966                         RTFREE(net->ro.ro_rt);
  967                         net->ro.ro_rt = NULL;
  968                 }
  969                 /* clear any cached source address */
  970                 if (net->src_addr_selected) {
  971                         sctp_free_ifa(net->ro._s_addr);
  972                         net->ro._s_addr = NULL;
  973                         net->src_addr_selected = 0;
  974                 }
  975         }
  976 }
  977 
  978 
  979 void
  980 sctp_assoc_immediate_retrans(struct sctp_tcb *stcb, struct sctp_nets *dstnet)
  981 {
  982         int error;
  983 
  984         if (dstnet->dest_state & SCTP_ADDR_UNCONFIRMED) {
  985                 return;
  986         }
  987         if (stcb->asoc.deleted_primary == NULL) {
  988                 return;
  989         }
  990         if (!TAILQ_EMPTY(&stcb->asoc.sent_queue)) {
  991                 SCTPDBG(SCTP_DEBUG_ASCONF1, "assoc_immediate_retrans: Deleted primary is ");
  992                 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, &stcb->asoc.deleted_primary->ro._l_addr.sa);
  993                 SCTPDBG(SCTP_DEBUG_ASCONF1, "Current Primary is ");
  994                 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, &stcb->asoc.primary_destination->ro._l_addr.sa);
  995                 sctp_timer_stop(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep, stcb,
  996                     stcb->asoc.deleted_primary,
  997                     SCTP_FROM_SCTP_ASCONF + SCTP_LOC_3);
  998                 stcb->asoc.num_send_timers_up--;
  999                 if (stcb->asoc.num_send_timers_up < 0) {
 1000                         stcb->asoc.num_send_timers_up = 0;
 1001                 }
 1002                 SCTP_TCB_LOCK_ASSERT(stcb);
 1003                 error = sctp_t3rxt_timer(stcb->sctp_ep, stcb,
 1004                     stcb->asoc.deleted_primary);
 1005                 if (error) {
 1006                         SCTP_INP_DECR_REF(stcb->sctp_ep);
 1007                         return;
 1008                 }
 1009                 SCTP_TCB_LOCK_ASSERT(stcb);
 1010 #ifdef SCTP_AUDITING_ENABLED
 1011                 sctp_auditing(4, stcb->sctp_ep, stcb, stcb->asoc.deleted_primary);
 1012 #endif
 1013                 sctp_chunk_output(stcb->sctp_ep, stcb, SCTP_OUTPUT_FROM_T3, SCTP_SO_NOT_LOCKED);
 1014                 if ((stcb->asoc.num_send_timers_up == 0) &&
 1015                     (stcb->asoc.sent_queue_cnt > 0)) {
 1016                         struct sctp_tmit_chunk *chk;
 1017 
 1018                         chk = TAILQ_FIRST(&stcb->asoc.sent_queue);
 1019                         sctp_timer_start(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep,
 1020                             stcb, chk->whoTo);
 1021                 }
 1022         }
 1023         return;
 1024 }
 1025 
 1026 static int
 1027     sctp_asconf_queue_mgmt(struct sctp_tcb *, struct sctp_ifa *, uint16_t);
 1028 
 1029 void
 1030 sctp_net_immediate_retrans(struct sctp_tcb *stcb, struct sctp_nets *net)
 1031 {
 1032         struct sctp_tmit_chunk *chk;
 1033 
 1034         SCTPDBG(SCTP_DEBUG_ASCONF1, "net_immediate_retrans: RTO is %d\n", net->RTO);
 1035         sctp_timer_stop(SCTP_TIMER_TYPE_SEND, stcb->sctp_ep, stcb, net,
 1036             SCTP_FROM_SCTP_ASCONF + SCTP_LOC_4);
 1037         stcb->asoc.cc_functions.sctp_set_initial_cc_param(stcb, net);
 1038         net->error_count = 0;
 1039         TAILQ_FOREACH(chk, &stcb->asoc.sent_queue, sctp_next) {
 1040                 if (chk->whoTo == net) {
 1041                         if (chk->sent < SCTP_DATAGRAM_RESEND) {
 1042                                 chk->sent = SCTP_DATAGRAM_RESEND;
 1043                                 sctp_ucount_incr(stcb->asoc.sent_queue_retran_cnt);
 1044                                 sctp_flight_size_decrease(chk);
 1045                                 sctp_total_flight_decrease(stcb, chk);
 1046                                 net->marked_retrans++;
 1047                                 stcb->asoc.marked_retrans++;
 1048                         }
 1049                 }
 1050         }
 1051         if (net->marked_retrans) {
 1052                 sctp_chunk_output(stcb->sctp_ep, stcb, SCTP_OUTPUT_FROM_T3, SCTP_SO_NOT_LOCKED);
 1053         }
 1054 }
 1055 
 1056 static void
 1057 sctp_path_check_and_react(struct sctp_tcb *stcb, struct sctp_ifa *newifa)
 1058 {
 1059         struct sctp_nets *net;
 1060         int addrnum, changed;
 1061 
 1062         /*
 1063          * If number of local valid addresses is 1, the valid address is
 1064          * probably newly added address. Several valid addresses in this
 1065          * association.  A source address may not be changed.  Additionally,
 1066          * they can be configured on a same interface as "alias" addresses.
 1067          * (by micchie)
 1068          */
 1069         addrnum = sctp_local_addr_count(stcb);
 1070         SCTPDBG(SCTP_DEBUG_ASCONF1, "p_check_react(): %d local addresses\n",
 1071             addrnum);
 1072         if (addrnum == 1) {
 1073                 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
 1074                         /* clear any cached route and source address */
 1075                         if (net->ro.ro_rt) {
 1076                                 RTFREE(net->ro.ro_rt);
 1077                                 net->ro.ro_rt = NULL;
 1078                         }
 1079                         if (net->src_addr_selected) {
 1080                                 sctp_free_ifa(net->ro._s_addr);
 1081                                 net->ro._s_addr = NULL;
 1082                                 net->src_addr_selected = 0;
 1083                         }
 1084                         /* Retransmit unacknowledged DATA chunks immediately */
 1085                         if (sctp_is_mobility_feature_on(stcb->sctp_ep,
 1086                             SCTP_MOBILITY_FASTHANDOFF)) {
 1087                                 sctp_net_immediate_retrans(stcb, net);
 1088                         }
 1089                         /* also, SET PRIMARY is maybe already sent */
 1090                 }
 1091                 return;
 1092         }
 1093         /* Multiple local addresses exsist in the association.  */
 1094         TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
 1095                 /* clear any cached route and source address */
 1096                 if (net->ro.ro_rt) {
 1097                         RTFREE(net->ro.ro_rt);
 1098                         net->ro.ro_rt = NULL;
 1099                 }
 1100                 if (net->src_addr_selected) {
 1101                         sctp_free_ifa(net->ro._s_addr);
 1102                         net->ro._s_addr = NULL;
 1103                         net->src_addr_selected = 0;
 1104                 }
 1105                 /*
 1106                  * Check if the nexthop is corresponding to the new address.
 1107                  * If the new address is corresponding to the current
 1108                  * nexthop, the path will be changed. If the new address is
 1109                  * NOT corresponding to the current nexthop, the path will
 1110                  * not be changed.
 1111                  */
 1112                 SCTP_RTALLOC((sctp_route_t *) & net->ro,
 1113                     stcb->sctp_ep->def_vrf_id,
 1114                     stcb->sctp_ep->fibnum);
 1115                 if (net->ro.ro_rt == NULL)
 1116                         continue;
 1117 
 1118                 changed = 0;
 1119                 switch (net->ro._l_addr.sa.sa_family) {
 1120 #ifdef INET
 1121                 case AF_INET:
 1122                         if (sctp_v4src_match_nexthop(newifa, (sctp_route_t *) & net->ro)) {
 1123                                 changed = 1;
 1124                         }
 1125                         break;
 1126 #endif
 1127 #ifdef INET6
 1128                 case AF_INET6:
 1129                         if (sctp_v6src_match_nexthop(
 1130                             &newifa->address.sin6, (sctp_route_t *) & net->ro)) {
 1131                                 changed = 1;
 1132                         }
 1133                         break;
 1134 #endif
 1135                 default:
 1136                         break;
 1137                 }
 1138                 /*
 1139                  * if the newly added address does not relate routing
 1140                  * information, we skip.
 1141                  */
 1142                 if (changed == 0)
 1143                         continue;
 1144                 /* Retransmit unacknowledged DATA chunks immediately */
 1145                 if (sctp_is_mobility_feature_on(stcb->sctp_ep,
 1146                     SCTP_MOBILITY_FASTHANDOFF)) {
 1147                         sctp_net_immediate_retrans(stcb, net);
 1148                 }
 1149                 /* Send SET PRIMARY for this new address */
 1150                 if (net == stcb->asoc.primary_destination) {
 1151                         (void)sctp_asconf_queue_mgmt(stcb, newifa,
 1152                             SCTP_SET_PRIM_ADDR);
 1153                 }
 1154         }
 1155 }
 1156 
 1157 /*
 1158  * process an ADD/DELETE IP ack from peer.
 1159  * addr: corresponding sctp_ifa to the address being added/deleted.
 1160  * type: SCTP_ADD_IP_ADDRESS or SCTP_DEL_IP_ADDRESS.
 1161  * flag: 1=success, 0=failure.
 1162  */
 1163 static void
 1164 sctp_asconf_addr_mgmt_ack(struct sctp_tcb *stcb, struct sctp_ifa *addr, uint32_t flag)
 1165 {
 1166         /*
 1167          * do the necessary asoc list work- if we get a failure indication,
 1168          * leave the address on the assoc's restricted list.  If we get a
 1169          * success indication, remove the address from the restricted list.
 1170          */
 1171         /*
 1172          * Note: this will only occur for ADD_IP_ADDRESS, since
 1173          * DEL_IP_ADDRESS is never actually added to the list...
 1174          */
 1175         if (flag) {
 1176                 /* success case, so remove from the restricted list */
 1177                 sctp_del_local_addr_restricted(stcb, addr);
 1178 
 1179                 if (sctp_is_mobility_feature_on(stcb->sctp_ep,
 1180                     SCTP_MOBILITY_BASE) ||
 1181                     sctp_is_mobility_feature_on(stcb->sctp_ep,
 1182                     SCTP_MOBILITY_FASTHANDOFF)) {
 1183                         sctp_path_check_and_react(stcb, addr);
 1184                         return;
 1185                 }
 1186                 /* clear any cached/topologically incorrect source addresses */
 1187                 sctp_asconf_nets_cleanup(stcb, addr->ifn_p);
 1188         }
 1189         /* else, leave it on the list */
 1190 }
 1191 
 1192 /*
 1193  * add an asconf add/delete/set primary IP address parameter to the queue.
 1194  * type = SCTP_ADD_IP_ADDRESS, SCTP_DEL_IP_ADDRESS, SCTP_SET_PRIM_ADDR.
 1195  * returns 0 if queued, -1 if not queued/removed.
 1196  * NOTE: if adding, but a delete for the same address is already scheduled
 1197  * (and not yet sent out), simply remove it from queue.  Same for deleting
 1198  * an address already scheduled for add.  If a duplicate operation is found,
 1199  * ignore the new one.
 1200  */
 1201 static int
 1202 sctp_asconf_queue_mgmt(struct sctp_tcb *stcb, struct sctp_ifa *ifa,
 1203     uint16_t type)
 1204 {
 1205         struct sctp_asconf_addr *aa, *aa_next;
 1206 
 1207         /* make sure the request isn't already in the queue */
 1208         TAILQ_FOREACH_SAFE(aa, &stcb->asoc.asconf_queue, next, aa_next) {
 1209                 /* address match? */
 1210                 if (sctp_asconf_addr_match(aa, &ifa->address.sa) == 0)
 1211                         continue;
 1212                 /*
 1213                  * is the request already in queue but not sent? pass the
 1214                  * request already sent in order to resolve the following
 1215                  * case: 1. arrival of ADD, then sent 2. arrival of DEL. we
 1216                  * can't remove the ADD request already sent 3. arrival of
 1217                  * ADD
 1218                  */
 1219                 if (aa->ap.aph.ph.param_type == type && aa->sent == 0) {
 1220                         return (-1);
 1221                 }
 1222                 /* is the negative request already in queue, and not sent */
 1223                 if ((aa->sent == 0) && (type == SCTP_ADD_IP_ADDRESS) &&
 1224                     (aa->ap.aph.ph.param_type == SCTP_DEL_IP_ADDRESS)) {
 1225                         /* add requested, delete already queued */
 1226                         TAILQ_REMOVE(&stcb->asoc.asconf_queue, aa, next);
 1227                         /* remove the ifa from the restricted list */
 1228                         sctp_del_local_addr_restricted(stcb, ifa);
 1229                         /* free the asconf param */
 1230                         SCTP_FREE(aa, SCTP_M_ASC_ADDR);
 1231                         SCTPDBG(SCTP_DEBUG_ASCONF2, "asconf_queue_mgmt: add removes queued entry\n");
 1232                         return (-1);
 1233                 }
 1234                 if ((aa->sent == 0) && (type == SCTP_DEL_IP_ADDRESS) &&
 1235                     (aa->ap.aph.ph.param_type == SCTP_ADD_IP_ADDRESS)) {
 1236                         /* delete requested, add already queued */
 1237                         TAILQ_REMOVE(&stcb->asoc.asconf_queue, aa, next);
 1238                         /* remove the aa->ifa from the restricted list */
 1239                         sctp_del_local_addr_restricted(stcb, aa->ifa);
 1240                         /* free the asconf param */
 1241                         SCTP_FREE(aa, SCTP_M_ASC_ADDR);
 1242                         SCTPDBG(SCTP_DEBUG_ASCONF2, "asconf_queue_mgmt: delete removes queued entry\n");
 1243                         return (-1);
 1244                 }
 1245         }                       /* for each aa */
 1246 
 1247         /* adding new request to the queue */
 1248         SCTP_MALLOC(aa, struct sctp_asconf_addr *, sizeof(*aa),
 1249             SCTP_M_ASC_ADDR);
 1250         if (aa == NULL) {
 1251                 /* didn't get memory */
 1252                 SCTPDBG(SCTP_DEBUG_ASCONF1, "asconf_queue_mgmt: failed to get memory!\n");
 1253                 return (-1);
 1254         }
 1255         aa->special_del = 0;
 1256         /* fill in asconf address parameter fields */
 1257         /* top level elements are "networked" during send */
 1258         aa->ap.aph.ph.param_type = type;
 1259         aa->ifa = ifa;
 1260         atomic_add_int(&ifa->refcount, 1);
 1261         /* correlation_id filled in during send routine later... */
 1262         switch (ifa->address.sa.sa_family) {
 1263 #ifdef INET6
 1264         case AF_INET6:
 1265                 {
 1266                         struct sockaddr_in6 *sin6;
 1267 
 1268                         sin6 = &ifa->address.sin6;
 1269                         aa->ap.addrp.ph.param_type = SCTP_IPV6_ADDRESS;
 1270                         aa->ap.addrp.ph.param_length = (sizeof(struct sctp_ipv6addr_param));
 1271                         aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_paramhdr) +
 1272                             sizeof(struct sctp_ipv6addr_param);
 1273                         memcpy(&aa->ap.addrp.addr, &sin6->sin6_addr,
 1274                             sizeof(struct in6_addr));
 1275                         break;
 1276                 }
 1277 #endif
 1278 #ifdef INET
 1279         case AF_INET:
 1280                 {
 1281                         struct sockaddr_in *sin;
 1282 
 1283                         sin = &ifa->address.sin;
 1284                         aa->ap.addrp.ph.param_type = SCTP_IPV4_ADDRESS;
 1285                         aa->ap.addrp.ph.param_length = (sizeof(struct sctp_ipv4addr_param));
 1286                         aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_paramhdr) +
 1287                             sizeof(struct sctp_ipv4addr_param);
 1288                         memcpy(&aa->ap.addrp.addr, &sin->sin_addr,
 1289                             sizeof(struct in_addr));
 1290                         break;
 1291                 }
 1292 #endif
 1293         default:
 1294                 /* invalid family! */
 1295                 SCTP_FREE(aa, SCTP_M_ASC_ADDR);
 1296                 sctp_free_ifa(ifa);
 1297                 return (-1);
 1298         }
 1299         aa->sent = 0;           /* clear sent flag */
 1300 
 1301         TAILQ_INSERT_TAIL(&stcb->asoc.asconf_queue, aa, next);
 1302 #ifdef SCTP_DEBUG
 1303         if (SCTP_BASE_SYSCTL(sctp_debug_on) & SCTP_DEBUG_ASCONF2) {
 1304                 if (type == SCTP_ADD_IP_ADDRESS) {
 1305                         SCTP_PRINTF("asconf_queue_mgmt: inserted asconf ADD_IP_ADDRESS: ");
 1306                         SCTPDBG_ADDR(SCTP_DEBUG_ASCONF2, &ifa->address.sa);
 1307                 } else if (type == SCTP_DEL_IP_ADDRESS) {
 1308                         SCTP_PRINTF("asconf_queue_mgmt: appended asconf DEL_IP_ADDRESS: ");
 1309                         SCTPDBG_ADDR(SCTP_DEBUG_ASCONF2, &ifa->address.sa);
 1310                 } else {
 1311                         SCTP_PRINTF("asconf_queue_mgmt: appended asconf SET_PRIM_ADDR: ");
 1312                         SCTPDBG_ADDR(SCTP_DEBUG_ASCONF2, &ifa->address.sa);
 1313                 }
 1314         }
 1315 #endif
 1316 
 1317         return (0);
 1318 }
 1319 
 1320 
 1321 /*
 1322  * add an asconf operation for the given ifa and type.
 1323  * type = SCTP_ADD_IP_ADDRESS, SCTP_DEL_IP_ADDRESS, SCTP_SET_PRIM_ADDR.
 1324  * returns 0 if completed, -1 if not completed, 1 if immediate send is
 1325  * advisable.
 1326  */
 1327 static int
 1328 sctp_asconf_queue_add(struct sctp_tcb *stcb, struct sctp_ifa *ifa,
 1329     uint16_t type)
 1330 {
 1331         uint32_t status;
 1332         int pending_delete_queued = 0;
 1333         int last;
 1334 
 1335         /* see if peer supports ASCONF */
 1336         if (stcb->asoc.asconf_supported == 0) {
 1337                 return (-1);
 1338         }
 1339         /*
 1340          * if this is deleting the last address from the assoc, mark it as
 1341          * pending.
 1342          */
 1343         if ((type == SCTP_DEL_IP_ADDRESS) && !stcb->asoc.asconf_del_pending) {
 1344                 if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
 1345                         last = (sctp_local_addr_count(stcb) == 0);
 1346                 } else {
 1347                         last = (sctp_local_addr_count(stcb) == 1);
 1348                 }
 1349                 if (last) {
 1350                         /* set the pending delete info only */
 1351                         stcb->asoc.asconf_del_pending = 1;
 1352                         stcb->asoc.asconf_addr_del_pending = ifa;
 1353                         atomic_add_int(&ifa->refcount, 1);
 1354                         SCTPDBG(SCTP_DEBUG_ASCONF2,
 1355                             "asconf_queue_add: mark delete last address pending\n");
 1356                         return (-1);
 1357                 }
 1358         }
 1359         /* queue an asconf parameter */
 1360         status = sctp_asconf_queue_mgmt(stcb, ifa, type);
 1361 
 1362         /*
 1363          * if this is an add, and there is a delete also pending (i.e. the
 1364          * last local address is being changed), queue the pending delete
 1365          * too.
 1366          */
 1367         if ((type == SCTP_ADD_IP_ADDRESS) && stcb->asoc.asconf_del_pending && (status == 0)) {
 1368                 /* queue in the pending delete */
 1369                 if (sctp_asconf_queue_mgmt(stcb,
 1370                     stcb->asoc.asconf_addr_del_pending,
 1371                     SCTP_DEL_IP_ADDRESS) == 0) {
 1372                         SCTPDBG(SCTP_DEBUG_ASCONF2, "asconf_queue_add: queing pending delete\n");
 1373                         pending_delete_queued = 1;
 1374                         /* clear out the pending delete info */
 1375                         stcb->asoc.asconf_del_pending = 0;
 1376                         sctp_free_ifa(stcb->asoc.asconf_addr_del_pending);
 1377                         stcb->asoc.asconf_addr_del_pending = NULL;
 1378                 }
 1379         }
 1380         if (pending_delete_queued) {
 1381                 struct sctp_nets *net;
 1382 
 1383                 /*
 1384                  * since we know that the only/last address is now being
 1385                  * changed in this case, reset the cwnd/rto on all nets to
 1386                  * start as a new address and path.  Also clear the error
 1387                  * counts to give the assoc the best chance to complete the
 1388                  * address change.
 1389                  */
 1390                 TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
 1391                         stcb->asoc.cc_functions.sctp_set_initial_cc_param(stcb,
 1392                             net);
 1393                         net->RTO = 0;
 1394                         net->error_count = 0;
 1395                 }
 1396                 stcb->asoc.overall_error_count = 0;
 1397                 if (SCTP_BASE_SYSCTL(sctp_logging_level) & SCTP_THRESHOLD_LOGGING) {
 1398                         sctp_misc_ints(SCTP_THRESHOLD_CLEAR,
 1399                             stcb->asoc.overall_error_count,
 1400                             0,
 1401                             SCTP_FROM_SCTP_ASCONF,
 1402                             __LINE__);
 1403                 }
 1404                 /* queue in an advisory set primary too */
 1405                 (void)sctp_asconf_queue_mgmt(stcb, ifa, SCTP_SET_PRIM_ADDR);
 1406                 /* let caller know we should send this out immediately */
 1407                 status = 1;
 1408         }
 1409         return (status);
 1410 }
 1411 
 1412 /*-
 1413  * add an asconf delete IP address parameter to the queue by sockaddr and
 1414  * possibly with no sctp_ifa available.  This is only called by the routine
 1415  * that checks the addresses in an INIT-ACK against the current address list.
 1416  * returns 0 if completed, non-zero if not completed.
 1417  * NOTE: if an add is already scheduled (and not yet sent out), simply
 1418  * remove it from queue.  If a duplicate operation is found, ignore the
 1419  * new one.
 1420  */
 1421 static int
 1422 sctp_asconf_queue_sa_delete(struct sctp_tcb *stcb, struct sockaddr *sa)
 1423 {
 1424         struct sctp_ifa *ifa;
 1425         struct sctp_asconf_addr *aa, *aa_next;
 1426 
 1427         if (stcb == NULL) {
 1428                 return (-1);
 1429         }
 1430         /* see if peer supports ASCONF */
 1431         if (stcb->asoc.asconf_supported == 0) {
 1432                 return (-1);
 1433         }
 1434         /* make sure the request isn't already in the queue */
 1435         TAILQ_FOREACH_SAFE(aa, &stcb->asoc.asconf_queue, next, aa_next) {
 1436                 /* address match? */
 1437                 if (sctp_asconf_addr_match(aa, sa) == 0)
 1438                         continue;
 1439                 /* is the request already in queue (sent or not) */
 1440                 if (aa->ap.aph.ph.param_type == SCTP_DEL_IP_ADDRESS) {
 1441                         return (-1);
 1442                 }
 1443                 /* is the negative request already in queue, and not sent */
 1444                 if (aa->sent == 1)
 1445                         continue;
 1446                 if (aa->ap.aph.ph.param_type == SCTP_ADD_IP_ADDRESS) {
 1447                         /* add already queued, so remove existing entry */
 1448                         TAILQ_REMOVE(&stcb->asoc.asconf_queue, aa, next);
 1449                         sctp_del_local_addr_restricted(stcb, aa->ifa);
 1450                         /* free the entry */
 1451                         SCTP_FREE(aa, SCTP_M_ASC_ADDR);
 1452                         return (-1);
 1453                 }
 1454         }                       /* for each aa */
 1455 
 1456         /* find any existing ifa-- NOTE ifa CAN be allowed to be NULL */
 1457         ifa = sctp_find_ifa_by_addr(sa, stcb->asoc.vrf_id, SCTP_ADDR_NOT_LOCKED);
 1458 
 1459         /* adding new request to the queue */
 1460         SCTP_MALLOC(aa, struct sctp_asconf_addr *, sizeof(*aa),
 1461             SCTP_M_ASC_ADDR);
 1462         if (aa == NULL) {
 1463                 /* didn't get memory */
 1464                 SCTPDBG(SCTP_DEBUG_ASCONF1,
 1465                     "sctp_asconf_queue_sa_delete: failed to get memory!\n");
 1466                 return (-1);
 1467         }
 1468         aa->special_del = 0;
 1469         /* fill in asconf address parameter fields */
 1470         /* top level elements are "networked" during send */
 1471         aa->ap.aph.ph.param_type = SCTP_DEL_IP_ADDRESS;
 1472         aa->ifa = ifa;
 1473         if (ifa)
 1474                 atomic_add_int(&ifa->refcount, 1);
 1475         /* correlation_id filled in during send routine later... */
 1476         switch (sa->sa_family) {
 1477 #ifdef INET6
 1478         case AF_INET6:
 1479                 {
 1480                         /* IPv6 address */
 1481                         struct sockaddr_in6 *sin6;
 1482 
 1483                         sin6 = (struct sockaddr_in6 *)sa;
 1484                         aa->ap.addrp.ph.param_type = SCTP_IPV6_ADDRESS;
 1485                         aa->ap.addrp.ph.param_length = (sizeof(struct sctp_ipv6addr_param));
 1486                         aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_paramhdr) + sizeof(struct sctp_ipv6addr_param);
 1487                         memcpy(&aa->ap.addrp.addr, &sin6->sin6_addr,
 1488                             sizeof(struct in6_addr));
 1489                         break;
 1490                 }
 1491 #endif
 1492 #ifdef INET
 1493         case AF_INET:
 1494                 {
 1495                         /* IPv4 address */
 1496                         struct sockaddr_in *sin = (struct sockaddr_in *)sa;
 1497 
 1498                         aa->ap.addrp.ph.param_type = SCTP_IPV4_ADDRESS;
 1499                         aa->ap.addrp.ph.param_length = (sizeof(struct sctp_ipv4addr_param));
 1500                         aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_paramhdr) + sizeof(struct sctp_ipv4addr_param);
 1501                         memcpy(&aa->ap.addrp.addr, &sin->sin_addr,
 1502                             sizeof(struct in_addr));
 1503                         break;
 1504                 }
 1505 #endif
 1506         default:
 1507                 /* invalid family! */
 1508                 SCTP_FREE(aa, SCTP_M_ASC_ADDR);
 1509                 if (ifa)
 1510                         sctp_free_ifa(ifa);
 1511                 return (-1);
 1512         }
 1513         aa->sent = 0;           /* clear sent flag */
 1514 
 1515         /* delete goes to the back of the queue */
 1516         TAILQ_INSERT_TAIL(&stcb->asoc.asconf_queue, aa, next);
 1517 
 1518         /* sa_ignore MEMLEAK {memory is put on the tailq} */
 1519         return (0);
 1520 }
 1521 
 1522 /*
 1523  * find a specific asconf param on our "sent" queue
 1524  */
 1525 static struct sctp_asconf_addr *
 1526 sctp_asconf_find_param(struct sctp_tcb *stcb, uint32_t correlation_id)
 1527 {
 1528         struct sctp_asconf_addr *aa;
 1529 
 1530         TAILQ_FOREACH(aa, &stcb->asoc.asconf_queue, next) {
 1531                 if (aa->ap.aph.correlation_id == correlation_id &&
 1532                     aa->sent == 1) {
 1533                         /* found it */
 1534                         return (aa);
 1535                 }
 1536         }
 1537         /* didn't find it */
 1538         return (NULL);
 1539 }
 1540 
 1541 /*
 1542  * process an SCTP_ERROR_CAUSE_IND for a ASCONF-ACK parameter and do
 1543  * notifications based on the error response
 1544  */
 1545 static void
 1546 sctp_asconf_process_error(struct sctp_tcb *stcb SCTP_UNUSED,
 1547     struct sctp_asconf_paramhdr *aph)
 1548 {
 1549         struct sctp_error_cause *eh;
 1550         struct sctp_paramhdr *ph;
 1551         uint16_t param_type;
 1552         uint16_t error_code;
 1553 
 1554         eh = (struct sctp_error_cause *)(aph + 1);
 1555         ph = (struct sctp_paramhdr *)(eh + 1);
 1556         /* validate lengths */
 1557         if (htons(eh->length) + sizeof(struct sctp_error_cause) >
 1558             htons(aph->ph.param_length)) {
 1559                 /* invalid error cause length */
 1560                 SCTPDBG(SCTP_DEBUG_ASCONF1,
 1561                     "asconf_process_error: cause element too long\n");
 1562                 return;
 1563         }
 1564         if (htons(ph->param_length) + sizeof(struct sctp_paramhdr) >
 1565             htons(eh->length)) {
 1566                 /* invalid included TLV length */
 1567                 SCTPDBG(SCTP_DEBUG_ASCONF1,
 1568                     "asconf_process_error: included TLV too long\n");
 1569                 return;
 1570         }
 1571         /* which error code ? */
 1572         error_code = ntohs(eh->code);
 1573         param_type = ntohs(aph->ph.param_type);
 1574         /* FIX: this should go back up the REMOTE_ERROR ULP notify */
 1575         switch (error_code) {
 1576         case SCTP_CAUSE_RESOURCE_SHORTAGE:
 1577                 /* we allow ourselves to "try again" for this error */
 1578                 break;
 1579         default:
 1580                 /* peer can't handle it... */
 1581                 switch (param_type) {
 1582                 case SCTP_ADD_IP_ADDRESS:
 1583                 case SCTP_DEL_IP_ADDRESS:
 1584                 case SCTP_SET_PRIM_ADDR:
 1585                         break;
 1586                 default:
 1587                         break;
 1588                 }
 1589         }
 1590 }
 1591 
 1592 /*
 1593  * process an asconf queue param.
 1594  * aparam: parameter to process, will be removed from the queue.
 1595  * flag: 1=success case, 0=failure case
 1596  */
 1597 static void
 1598 sctp_asconf_process_param_ack(struct sctp_tcb *stcb,
 1599     struct sctp_asconf_addr *aparam, uint32_t flag)
 1600 {
 1601         uint16_t param_type;
 1602 
 1603         /* process this param */
 1604         param_type = aparam->ap.aph.ph.param_type;
 1605         switch (param_type) {
 1606         case SCTP_ADD_IP_ADDRESS:
 1607                 SCTPDBG(SCTP_DEBUG_ASCONF1,
 1608                     "process_param_ack: added IP address\n");
 1609                 sctp_asconf_addr_mgmt_ack(stcb, aparam->ifa, flag);
 1610                 break;
 1611         case SCTP_DEL_IP_ADDRESS:
 1612                 SCTPDBG(SCTP_DEBUG_ASCONF1,
 1613                     "process_param_ack: deleted IP address\n");
 1614                 /* nothing really to do... lists already updated */
 1615                 break;
 1616         case SCTP_SET_PRIM_ADDR:
 1617                 SCTPDBG(SCTP_DEBUG_ASCONF1,
 1618                     "process_param_ack: set primary IP address\n");
 1619                 /* nothing to do... peer may start using this addr */
 1620                 break;
 1621         default:
 1622                 /* should NEVER happen */
 1623                 break;
 1624         }
 1625 
 1626         /* remove the param and free it */
 1627         TAILQ_REMOVE(&stcb->asoc.asconf_queue, aparam, next);
 1628         if (aparam->ifa)
 1629                 sctp_free_ifa(aparam->ifa);
 1630         SCTP_FREE(aparam, SCTP_M_ASC_ADDR);
 1631 }
 1632 
 1633 /*
 1634  * cleanup from a bad asconf ack parameter
 1635  */
 1636 static void
 1637 sctp_asconf_ack_clear(struct sctp_tcb *stcb SCTP_UNUSED)
 1638 {
 1639         /* assume peer doesn't really know how to do asconfs */
 1640         /* XXX we could free the pending queue here */
 1641 
 1642 }
 1643 
 1644 void
 1645 sctp_handle_asconf_ack(struct mbuf *m, int offset,
 1646     struct sctp_asconf_ack_chunk *cp, struct sctp_tcb *stcb,
 1647     struct sctp_nets *net, int *abort_no_unlock)
 1648 {
 1649         struct sctp_association *asoc;
 1650         uint32_t serial_num;
 1651         uint16_t ack_length;
 1652         struct sctp_asconf_paramhdr *aph;
 1653         struct sctp_asconf_addr *aa, *aa_next;
 1654         uint32_t last_error_id = 0;     /* last error correlation id */
 1655         uint32_t id;
 1656         struct sctp_asconf_addr *ap;
 1657 
 1658         /* asconf param buffer */
 1659         uint8_t aparam_buf[SCTP_PARAM_BUFFER_SIZE];
 1660 
 1661         /* verify minimum length */
 1662         if (ntohs(cp->ch.chunk_length) < sizeof(struct sctp_asconf_ack_chunk)) {
 1663                 SCTPDBG(SCTP_DEBUG_ASCONF1,
 1664                     "handle_asconf_ack: chunk too small = %xh\n",
 1665                     ntohs(cp->ch.chunk_length));
 1666                 return;
 1667         }
 1668         asoc = &stcb->asoc;
 1669         serial_num = ntohl(cp->serial_number);
 1670 
 1671         /*
 1672          * NOTE: we may want to handle this differently- currently, we will
 1673          * abort when we get an ack for the expected serial number + 1 (eg.
 1674          * we didn't send it), process an ack normally if it is the expected
 1675          * serial number, and re-send the previous ack for *ALL* other
 1676          * serial numbers
 1677          */
 1678 
 1679         /*
 1680          * if the serial number is the next expected, but I didn't send it,
 1681          * abort the asoc, since someone probably just hijacked us...
 1682          */
 1683         if (serial_num == (asoc->asconf_seq_out + 1)) {
 1684                 struct mbuf *op_err;
 1685                 char msg[SCTP_DIAG_INFO_LEN];
 1686 
 1687                 SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf_ack: got unexpected next serial number! Aborting asoc!\n");
 1688                 snprintf(msg, sizeof(msg), "Never sent serial number %8.8x",
 1689                     serial_num);
 1690                 op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
 1691                 sctp_abort_an_association(stcb->sctp_ep, stcb, op_err, SCTP_SO_NOT_LOCKED);
 1692                 *abort_no_unlock = 1;
 1693                 return;
 1694         }
 1695         if (serial_num != asoc->asconf_seq_out_acked + 1) {
 1696                 /* got a duplicate/unexpected ASCONF-ACK */
 1697                 SCTPDBG(SCTP_DEBUG_ASCONF1, "handle_asconf_ack: got duplicate/unexpected serial number = %xh (expected = %xh)\n",
 1698                     serial_num, asoc->asconf_seq_out_acked + 1);
 1699                 return;
 1700         }
 1701         if (serial_num == asoc->asconf_seq_out - 1) {
 1702                 /* stop our timer */
 1703                 sctp_timer_stop(SCTP_TIMER_TYPE_ASCONF, stcb->sctp_ep, stcb, net,
 1704                     SCTP_FROM_SCTP_ASCONF + SCTP_LOC_5);
 1705         }
 1706         /* process the ASCONF-ACK contents */
 1707         ack_length = ntohs(cp->ch.chunk_length) -
 1708             sizeof(struct sctp_asconf_ack_chunk);
 1709         offset += sizeof(struct sctp_asconf_ack_chunk);
 1710         /* process through all parameters */
 1711         while (ack_length >= sizeof(struct sctp_asconf_paramhdr)) {
 1712                 unsigned int param_length, param_type;
 1713 
 1714                 /* get pointer to next asconf parameter */
 1715                 aph = (struct sctp_asconf_paramhdr *)sctp_m_getptr(m, offset,
 1716                     sizeof(struct sctp_asconf_paramhdr), aparam_buf);
 1717                 if (aph == NULL) {
 1718                         /* can't get an asconf paramhdr */
 1719                         sctp_asconf_ack_clear(stcb);
 1720                         return;
 1721                 }
 1722                 param_type = ntohs(aph->ph.param_type);
 1723                 param_length = ntohs(aph->ph.param_length);
 1724                 if (param_length > ack_length) {
 1725                         sctp_asconf_ack_clear(stcb);
 1726                         return;
 1727                 }
 1728                 if (param_length < sizeof(struct sctp_paramhdr)) {
 1729                         sctp_asconf_ack_clear(stcb);
 1730                         return;
 1731                 }
 1732                 /* get the complete parameter... */
 1733                 if (param_length > sizeof(aparam_buf)) {
 1734                         SCTPDBG(SCTP_DEBUG_ASCONF1,
 1735                             "param length (%u) larger than buffer size!\n", param_length);
 1736                         sctp_asconf_ack_clear(stcb);
 1737                         return;
 1738                 }
 1739                 aph = (struct sctp_asconf_paramhdr *)sctp_m_getptr(m, offset, param_length, aparam_buf);
 1740                 if (aph == NULL) {
 1741                         sctp_asconf_ack_clear(stcb);
 1742                         return;
 1743                 }
 1744                 /* correlation_id is transparent to peer, no ntohl needed */
 1745                 id = aph->correlation_id;
 1746 
 1747                 switch (param_type) {
 1748                 case SCTP_ERROR_CAUSE_IND:
 1749                         last_error_id = id;
 1750                         /* find the corresponding asconf param in our queue */
 1751                         ap = sctp_asconf_find_param(stcb, id);
 1752                         if (ap == NULL) {
 1753                                 /* hmm... can't find this in our queue! */
 1754                                 break;
 1755                         }
 1756                         /* process the parameter, failed flag */
 1757                         sctp_asconf_process_param_ack(stcb, ap, 0);
 1758                         /* process the error response */
 1759                         sctp_asconf_process_error(stcb, aph);
 1760                         break;
 1761                 case SCTP_SUCCESS_REPORT:
 1762                         /* find the corresponding asconf param in our queue */
 1763                         ap = sctp_asconf_find_param(stcb, id);
 1764                         if (ap == NULL) {
 1765                                 /* hmm... can't find this in our queue! */
 1766                                 break;
 1767                         }
 1768                         /* process the parameter, success flag */
 1769                         sctp_asconf_process_param_ack(stcb, ap, 1);
 1770                         break;
 1771                 default:
 1772                         break;
 1773                 }               /* switch */
 1774 
 1775                 /* update remaining ASCONF-ACK message length to process */
 1776                 ack_length -= SCTP_SIZE32(param_length);
 1777                 if (ack_length <= 0) {
 1778                         /* no more data in the mbuf chain */
 1779                         break;
 1780                 }
 1781                 offset += SCTP_SIZE32(param_length);
 1782         }                       /* while */
 1783 
 1784         /*
 1785          * if there are any "sent" params still on the queue, these are
 1786          * implicitly "success", or "failed" (if we got an error back) ...
 1787          * so process these appropriately
 1788          * 
 1789          * we assume that the correlation_id's are monotonically increasing
 1790          * beginning from 1 and that we don't have *that* many outstanding
 1791          * at any given time
 1792          */
 1793         if (last_error_id == 0)
 1794                 last_error_id--;/* set to "max" value */
 1795         TAILQ_FOREACH_SAFE(aa, &stcb->asoc.asconf_queue, next, aa_next) {
 1796                 if (aa->sent == 1) {
 1797                         /*
 1798                          * implicitly successful or failed if correlation_id
 1799                          * < last_error_id, then success else, failure
 1800                          */
 1801                         if (aa->ap.aph.correlation_id < last_error_id)
 1802                                 sctp_asconf_process_param_ack(stcb, aa, 1);
 1803                         else
 1804                                 sctp_asconf_process_param_ack(stcb, aa, 0);
 1805                 } else {
 1806                         /*
 1807                          * since we always process in order (FIFO queue) if
 1808                          * we reach one that hasn't been sent, the rest
 1809                          * should not have been sent either. so, we're
 1810                          * done...
 1811                          */
 1812                         break;
 1813                 }
 1814         }
 1815 
 1816         /* update the next sequence number to use */
 1817         asoc->asconf_seq_out_acked++;
 1818         /* remove the old ASCONF on our outbound queue */
 1819         sctp_toss_old_asconf(stcb);
 1820         if (!TAILQ_EMPTY(&stcb->asoc.asconf_queue)) {
 1821 #ifdef SCTP_TIMER_BASED_ASCONF
 1822                 /* we have more params, so restart our timer */
 1823                 sctp_timer_start(SCTP_TIMER_TYPE_ASCONF, stcb->sctp_ep,
 1824                     stcb, net);
 1825 #else
 1826                 /* we have more params, so send out more */
 1827                 sctp_send_asconf(stcb, net, SCTP_ADDR_NOT_LOCKED);
 1828 #endif
 1829         }
 1830 }
 1831 
 1832 #ifdef INET6
 1833 static uint32_t
 1834 sctp_is_scopeid_in_nets(struct sctp_tcb *stcb, struct sockaddr *sa)
 1835 {
 1836         struct sockaddr_in6 *sin6, *net6;
 1837         struct sctp_nets *net;
 1838 
 1839         if (sa->sa_family != AF_INET6) {
 1840                 /* wrong family */
 1841                 return (0);
 1842         }
 1843         sin6 = (struct sockaddr_in6 *)sa;
 1844         if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) == 0) {
 1845                 /* not link local address */
 1846                 return (0);
 1847         }
 1848         /* hunt through our destination nets list for this scope_id */
 1849         TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
 1850                 if (((struct sockaddr *)(&net->ro._l_addr))->sa_family !=
 1851                     AF_INET6)
 1852                         continue;
 1853                 net6 = (struct sockaddr_in6 *)&net->ro._l_addr;
 1854                 if (IN6_IS_ADDR_LINKLOCAL(&net6->sin6_addr) == 0)
 1855                         continue;
 1856                 if (sctp_is_same_scope(sin6, net6)) {
 1857                         /* found one */
 1858                         return (1);
 1859                 }
 1860         }
 1861         /* didn't find one */
 1862         return (0);
 1863 }
 1864 
 1865 #endif
 1866 
 1867 /*
 1868  * address management functions
 1869  */
 1870 static void
 1871 sctp_addr_mgmt_assoc(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
 1872     struct sctp_ifa *ifa, uint16_t type, int addr_locked)
 1873 {
 1874         int status;
 1875 
 1876         if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0 ||
 1877             sctp_is_feature_off(inp, SCTP_PCB_FLAGS_DO_ASCONF)) {
 1878                 /* subset bound, no ASCONF allowed case, so ignore */
 1879                 return;
 1880         }
 1881         /*
 1882          * note: we know this is not the subset bound, no ASCONF case eg.
 1883          * this is boundall or subset bound w/ASCONF allowed
 1884          */
 1885 
 1886         /* first, make sure that the address is IPv4 or IPv6 and not jailed */
 1887         switch (ifa->address.sa.sa_family) {
 1888 #ifdef INET6
 1889         case AF_INET6:
 1890                 if (prison_check_ip6(inp->ip_inp.inp.inp_cred,
 1891                     &ifa->address.sin6.sin6_addr) != 0) {
 1892                         return;
 1893                 }
 1894                 break;
 1895 #endif
 1896 #ifdef INET
 1897         case AF_INET:
 1898                 if (prison_check_ip4(inp->ip_inp.inp.inp_cred,
 1899                     &ifa->address.sin.sin_addr) != 0) {
 1900                         return;
 1901                 }
 1902                 break;
 1903 #endif
 1904         default:
 1905                 return;
 1906         }
 1907 #ifdef INET6
 1908         /* make sure we're "allowed" to add this type of addr */
 1909         if (ifa->address.sa.sa_family == AF_INET6) {
 1910                 /* invalid if we're not a v6 endpoint */
 1911                 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0)
 1912                         return;
 1913                 /* is the v6 addr really valid ? */
 1914                 if (ifa->localifa_flags & SCTP_ADDR_IFA_UNUSEABLE) {
 1915                         return;
 1916                 }
 1917         }
 1918 #endif
 1919         /* put this address on the "pending/do not use yet" list */
 1920         sctp_add_local_addr_restricted(stcb, ifa);
 1921         /*
 1922          * check address scope if address is out of scope, don't queue
 1923          * anything... note: this would leave the address on both inp and
 1924          * asoc lists
 1925          */
 1926         switch (ifa->address.sa.sa_family) {
 1927 #ifdef INET6
 1928         case AF_INET6:
 1929                 {
 1930                         struct sockaddr_in6 *sin6;
 1931 
 1932                         sin6 = &ifa->address.sin6;
 1933                         if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
 1934                                 /* we skip unspecifed addresses */
 1935                                 return;
 1936                         }
 1937                         if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
 1938                                 if (stcb->asoc.scope.local_scope == 0) {
 1939                                         return;
 1940                                 }
 1941                                 /* is it the right link local scope? */
 1942                                 if (sctp_is_scopeid_in_nets(stcb, &ifa->address.sa) == 0) {
 1943                                         return;
 1944                                 }
 1945                         }
 1946                         if (stcb->asoc.scope.site_scope == 0 &&
 1947                             IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr)) {
 1948                                 return;
 1949                         }
 1950                         break;
 1951                 }
 1952 #endif
 1953 #ifdef INET
 1954         case AF_INET:
 1955                 {
 1956                         struct sockaddr_in *sin;
 1957                         struct in6pcb *inp6;
 1958 
 1959                         inp6 = (struct in6pcb *)&inp->ip_inp.inp;
 1960                         /* invalid if we are a v6 only endpoint */
 1961                         if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
 1962                             SCTP_IPV6_V6ONLY(inp6))
 1963                                 return;
 1964 
 1965                         sin = &ifa->address.sin;
 1966                         if (sin->sin_addr.s_addr == 0) {
 1967                                 /* we skip unspecifed addresses */
 1968                                 return;
 1969                         }
 1970                         if (stcb->asoc.scope.ipv4_local_scope == 0 &&
 1971                             IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) {
 1972                                 return;
 1973                         }
 1974                         break;
 1975                 }
 1976 #endif
 1977         default:
 1978                 /* else, not AF_INET or AF_INET6, so skip */
 1979                 return;
 1980         }
 1981 
 1982         /* queue an asconf for this address add/delete */
 1983         if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_DO_ASCONF)) {
 1984                 /* does the peer do asconf? */
 1985                 if (stcb->asoc.asconf_supported) {
 1986                         /* queue an asconf for this addr */
 1987                         status = sctp_asconf_queue_add(stcb, ifa, type);
 1988 
 1989                         /*
 1990                          * if queued ok, and in the open state, send out the
 1991                          * ASCONF.  If in the non-open state, these will be
 1992                          * sent when the state goes open.
 1993                          */
 1994                         if (status == 0 &&
 1995                             ((SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_OPEN) ||
 1996                             (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_SHUTDOWN_RECEIVED))) {
 1997 #ifdef SCTP_TIMER_BASED_ASCONF
 1998                                 sctp_timer_start(SCTP_TIMER_TYPE_ASCONF, inp,
 1999                                     stcb, stcb->asoc.primary_destination);
 2000 #else
 2001                                 sctp_send_asconf(stcb, NULL, addr_locked);
 2002 #endif
 2003                         }
 2004                 }
 2005         }
 2006 }
 2007 
 2008 
 2009 int
 2010 sctp_asconf_iterator_ep(struct sctp_inpcb *inp, void *ptr, uint32_t val SCTP_UNUSED)
 2011 {
 2012         struct sctp_asconf_iterator *asc;
 2013         struct sctp_ifa *ifa;
 2014         struct sctp_laddr *l;
 2015         int cnt_invalid = 0;
 2016 
 2017         asc = (struct sctp_asconf_iterator *)ptr;
 2018         LIST_FOREACH(l, &asc->list_of_work, sctp_nxt_addr) {
 2019                 ifa = l->ifa;
 2020                 switch (ifa->address.sa.sa_family) {
 2021 #ifdef INET6
 2022                 case AF_INET6:
 2023                         /* invalid if we're not a v6 endpoint */
 2024                         if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) {
 2025                                 cnt_invalid++;
 2026                                 if (asc->cnt == cnt_invalid)
 2027                                         return (1);
 2028                         }
 2029                         break;
 2030 #endif
 2031 #ifdef INET
 2032                 case AF_INET:
 2033                         {
 2034                                 /* invalid if we are a v6 only endpoint */
 2035                                 struct in6pcb *inp6;
 2036 
 2037                                 inp6 = (struct in6pcb *)&inp->ip_inp.inp;
 2038                                 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
 2039                                     SCTP_IPV6_V6ONLY(inp6)) {
 2040                                         cnt_invalid++;
 2041                                         if (asc->cnt == cnt_invalid)
 2042                                                 return (1);
 2043                                 }
 2044                                 break;
 2045                         }
 2046 #endif
 2047                 default:
 2048                         /* invalid address family */
 2049                         cnt_invalid++;
 2050                         if (asc->cnt == cnt_invalid)
 2051                                 return (1);
 2052                 }
 2053         }
 2054         return (0);
 2055 }
 2056 
 2057 static int
 2058 sctp_asconf_iterator_ep_end(struct sctp_inpcb *inp, void *ptr, uint32_t val SCTP_UNUSED)
 2059 {
 2060         struct sctp_ifa *ifa;
 2061         struct sctp_asconf_iterator *asc;
 2062         struct sctp_laddr *laddr, *nladdr, *l;
 2063 
 2064         /* Only for specific case not bound all */
 2065         asc = (struct sctp_asconf_iterator *)ptr;
 2066         LIST_FOREACH(l, &asc->list_of_work, sctp_nxt_addr) {
 2067                 ifa = l->ifa;
 2068                 if (l->action == SCTP_ADD_IP_ADDRESS) {
 2069                         LIST_FOREACH(laddr, &inp->sctp_addr_list,
 2070                             sctp_nxt_addr) {
 2071                                 if (laddr->ifa == ifa) {
 2072                                         laddr->action = 0;
 2073                                         break;
 2074                                 }
 2075                         }
 2076                 } else if (l->action == SCTP_DEL_IP_ADDRESS) {
 2077                         LIST_FOREACH_SAFE(laddr, &inp->sctp_addr_list, sctp_nxt_addr, nladdr) {
 2078                                 /* remove only after all guys are done */
 2079                                 if (laddr->ifa == ifa) {
 2080                                         sctp_del_local_addr_ep(inp, ifa);
 2081                                 }
 2082                         }
 2083                 }
 2084         }
 2085         return (0);
 2086 }
 2087 
 2088 void
 2089 sctp_asconf_iterator_stcb(struct sctp_inpcb *inp, struct sctp_tcb *stcb,
 2090     void *ptr, uint32_t val SCTP_UNUSED)
 2091 {
 2092         struct sctp_asconf_iterator *asc;
 2093         struct sctp_ifa *ifa;
 2094         struct sctp_laddr *l;
 2095         int cnt_invalid = 0;
 2096         int type, status;
 2097         int num_queued = 0;
 2098 
 2099         asc = (struct sctp_asconf_iterator *)ptr;
 2100         LIST_FOREACH(l, &asc->list_of_work, sctp_nxt_addr) {
 2101                 ifa = l->ifa;
 2102                 type = l->action;
 2103 
 2104                 /* address's vrf_id must be the vrf_id of the assoc */
 2105                 if (ifa->vrf_id != stcb->asoc.vrf_id) {
 2106                         continue;
 2107                 }
 2108                 /* Same checks again for assoc */
 2109                 switch (ifa->address.sa.sa_family) {
 2110 #ifdef INET6
 2111                 case AF_INET6:
 2112                         {
 2113                                 /* invalid if we're not a v6 endpoint */
 2114                                 struct sockaddr_in6 *sin6;
 2115 
 2116                                 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) == 0) {
 2117                                         cnt_invalid++;
 2118                                         if (asc->cnt == cnt_invalid)
 2119                                                 return;
 2120                                         else
 2121                                                 continue;
 2122                                 }
 2123                                 sin6 = &ifa->address.sin6;
 2124                                 if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
 2125                                         /* we skip unspecifed addresses */
 2126                                         continue;
 2127                                 }
 2128                                 if (prison_check_ip6(inp->ip_inp.inp.inp_cred,
 2129                                     &sin6->sin6_addr) != 0) {
 2130                                         continue;
 2131                                 }
 2132                                 if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
 2133                                         if (stcb->asoc.scope.local_scope == 0) {
 2134                                                 continue;
 2135                                         }
 2136                                         /* is it the right link local scope? */
 2137                                         if (sctp_is_scopeid_in_nets(stcb, &ifa->address.sa) == 0) {
 2138                                                 continue;
 2139                                         }
 2140                                 }
 2141                                 break;
 2142                         }
 2143 #endif
 2144 #ifdef INET
 2145                 case AF_INET:
 2146                         {
 2147                                 /* invalid if we are a v6 only endpoint */
 2148                                 struct in6pcb *inp6;
 2149                                 struct sockaddr_in *sin;
 2150 
 2151                                 inp6 = (struct in6pcb *)&inp->ip_inp.inp;
 2152                                 /* invalid if we are a v6 only endpoint */
 2153                                 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
 2154                                     SCTP_IPV6_V6ONLY(inp6))
 2155                                         continue;
 2156 
 2157                                 sin = &ifa->address.sin;
 2158                                 if (sin->sin_addr.s_addr == 0) {
 2159                                         /* we skip unspecifed addresses */
 2160                                         continue;
 2161                                 }
 2162                                 if (prison_check_ip4(inp->ip_inp.inp.inp_cred,
 2163                                     &sin->sin_addr) != 0) {
 2164                                         continue;
 2165                                 }
 2166                                 if (stcb->asoc.scope.ipv4_local_scope == 0 &&
 2167                                     IN4_ISPRIVATE_ADDRESS(&sin->sin_addr)) {
 2168                                         continue;
 2169                                 }
 2170                                 if ((inp->sctp_flags & SCTP_PCB_FLAGS_BOUND_V6) &&
 2171                                     SCTP_IPV6_V6ONLY(inp6)) {
 2172                                         cnt_invalid++;
 2173                                         if (asc->cnt == cnt_invalid)
 2174                                                 return;
 2175                                         else
 2176                                                 continue;
 2177                                 }
 2178                                 break;
 2179                         }
 2180 #endif
 2181                 default:
 2182                         /* invalid address family */
 2183                         cnt_invalid++;
 2184                         if (asc->cnt == cnt_invalid)
 2185                                 return;
 2186                         else
 2187                                 continue;
 2188                         break;
 2189                 }
 2190 
 2191                 if (type == SCTP_ADD_IP_ADDRESS) {
 2192                         /* prevent this address from being used as a source */
 2193                         sctp_add_local_addr_restricted(stcb, ifa);
 2194                 } else if (type == SCTP_DEL_IP_ADDRESS) {
 2195                         struct sctp_nets *net;
 2196 
 2197                         TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
 2198                                 sctp_rtentry_t *rt;
 2199 
 2200                                 /* delete this address if cached */
 2201                                 if (net->ro._s_addr == ifa) {
 2202                                         sctp_free_ifa(net->ro._s_addr);
 2203                                         net->ro._s_addr = NULL;
 2204                                         net->src_addr_selected = 0;
 2205                                         rt = net->ro.ro_rt;
 2206                                         if (rt) {
 2207                                                 RTFREE(rt);
 2208                                                 net->ro.ro_rt = NULL;
 2209                                         }
 2210                                         /*
 2211                                          * Now we deleted our src address,
 2212                                          * should we not also now reset the
 2213                                          * cwnd/rto to start as if its a new
 2214                                          * address?
 2215                                          */
 2216                                         stcb->asoc.cc_functions.sctp_set_initial_cc_param(stcb, net);
 2217                                         net->RTO = 0;
 2218 
 2219                                 }
 2220                         }
 2221                 } else if (type == SCTP_SET_PRIM_ADDR) {
 2222                         if ((stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) == 0) {
 2223                                 /* must validate the ifa is in the ep */
 2224                                 if (sctp_is_addr_in_ep(stcb->sctp_ep, ifa) == 0) {
 2225                                         continue;
 2226                                 }
 2227                         } else {
 2228                                 /* Need to check scopes for this guy */
 2229                                 if (sctp_is_address_in_scope(ifa, &stcb->asoc.scope, 0) == 0) {
 2230                                         continue;
 2231                                 }
 2232                         }
 2233                 }
 2234                 /* queue an asconf for this address add/delete */
 2235                 if (sctp_is_feature_on(inp, SCTP_PCB_FLAGS_DO_ASCONF) &&
 2236                     stcb->asoc.asconf_supported == 1) {
 2237                         /* queue an asconf for this addr */
 2238                         status = sctp_asconf_queue_add(stcb, ifa, type);
 2239                         /*
 2240                          * if queued ok, and in the open state, update the
 2241                          * count of queued params.  If in the non-open
 2242                          * state, these get sent when the assoc goes open.
 2243                          */
 2244                         if ((SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_OPEN) ||
 2245                             (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
 2246                                 if (status >= 0) {
 2247                                         num_queued++;
 2248                                 }
 2249                         }
 2250                 }
 2251         }
 2252         /*
 2253          * If we have queued params in the open state, send out an ASCONF.
 2254          */
 2255         if (num_queued > 0) {
 2256                 sctp_send_asconf(stcb, NULL, SCTP_ADDR_NOT_LOCKED);
 2257         }
 2258 }
 2259 
 2260 void
 2261 sctp_asconf_iterator_end(void *ptr, uint32_t val SCTP_UNUSED)
 2262 {
 2263         struct sctp_asconf_iterator *asc;
 2264         struct sctp_ifa *ifa;
 2265         struct sctp_laddr *l, *nl;
 2266 
 2267         asc = (struct sctp_asconf_iterator *)ptr;
 2268         LIST_FOREACH_SAFE(l, &asc->list_of_work, sctp_nxt_addr, nl) {
 2269                 ifa = l->ifa;
 2270                 if (l->action == SCTP_ADD_IP_ADDRESS) {
 2271                         /* Clear the defer use flag */
 2272                         ifa->localifa_flags &= ~SCTP_ADDR_DEFER_USE;
 2273                 }
 2274                 sctp_free_ifa(ifa);
 2275                 SCTP_ZONE_FREE(SCTP_BASE_INFO(ipi_zone_laddr), l);
 2276                 SCTP_DECR_LADDR_COUNT();
 2277         }
 2278         SCTP_FREE(asc, SCTP_M_ASC_IT);
 2279 }
 2280 
 2281 /*
 2282  * sa is the sockaddr to ask the peer to set primary to.
 2283  * returns: 0 = completed, -1 = error
 2284  */
 2285 int32_t
 2286 sctp_set_primary_ip_address_sa(struct sctp_tcb *stcb, struct sockaddr *sa)
 2287 {
 2288         uint32_t vrf_id;
 2289         struct sctp_ifa *ifa;
 2290 
 2291         /* find the ifa for the desired set primary */
 2292         vrf_id = stcb->asoc.vrf_id;
 2293         ifa = sctp_find_ifa_by_addr(sa, vrf_id, SCTP_ADDR_NOT_LOCKED);
 2294         if (ifa == NULL) {
 2295                 /* Invalid address */
 2296                 return (-1);
 2297         }
 2298         /* queue an ASCONF:SET_PRIM_ADDR to be sent */
 2299         if (!sctp_asconf_queue_add(stcb, ifa, SCTP_SET_PRIM_ADDR)) {
 2300                 /* set primary queuing succeeded */
 2301                 SCTPDBG(SCTP_DEBUG_ASCONF1,
 2302                     "set_primary_ip_address_sa: queued on tcb=%p, ",
 2303                     (void *)stcb);
 2304                 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
 2305                 if ((SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_OPEN) ||
 2306                     (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
 2307 #ifdef SCTP_TIMER_BASED_ASCONF
 2308                         sctp_timer_start(SCTP_TIMER_TYPE_ASCONF,
 2309                             stcb->sctp_ep, stcb,
 2310                             stcb->asoc.primary_destination);
 2311 #else
 2312                         sctp_send_asconf(stcb, NULL, SCTP_ADDR_NOT_LOCKED);
 2313 #endif
 2314                 }
 2315         } else {
 2316                 SCTPDBG(SCTP_DEBUG_ASCONF1, "set_primary_ip_address_sa: failed to add to queue on tcb=%p, ",
 2317                     (void *)stcb);
 2318                 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, sa);
 2319                 return (-1);
 2320         }
 2321         return (0);
 2322 }
 2323 
 2324 void
 2325 sctp_set_primary_ip_address(struct sctp_ifa *ifa)
 2326 {
 2327         struct sctp_inpcb *inp;
 2328 
 2329         /* go through all our PCB's */
 2330         LIST_FOREACH(inp, &SCTP_BASE_INFO(listhead), sctp_list) {
 2331                 struct sctp_tcb *stcb;
 2332 
 2333                 /* process for all associations for this endpoint */
 2334                 LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
 2335                         /* queue an ASCONF:SET_PRIM_ADDR to be sent */
 2336                         if (!sctp_asconf_queue_add(stcb, ifa,
 2337                             SCTP_SET_PRIM_ADDR)) {
 2338                                 /* set primary queuing succeeded */
 2339                                 SCTPDBG(SCTP_DEBUG_ASCONF1, "set_primary_ip_address: queued on stcb=%p, ",
 2340                                     (void *)stcb);
 2341                                 SCTPDBG_ADDR(SCTP_DEBUG_ASCONF1, &ifa->address.sa);
 2342                                 if ((SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_OPEN) ||
 2343                                     (SCTP_GET_STATE(&stcb->asoc) == SCTP_STATE_SHUTDOWN_RECEIVED)) {
 2344 #ifdef SCTP_TIMER_BASED_ASCONF
 2345                                         sctp_timer_start(SCTP_TIMER_TYPE_ASCONF,
 2346                                             stcb->sctp_ep, stcb,
 2347                                             stcb->asoc.primary_destination);
 2348 #else
 2349                                         sctp_send_asconf(stcb, NULL, SCTP_ADDR_NOT_LOCKED);
 2350 #endif
 2351                                 }
 2352                         }
 2353                 }               /* for each stcb */
 2354         }                       /* for each inp */
 2355 }
 2356 
 2357 int
 2358 sctp_is_addr_pending(struct sctp_tcb *stcb, struct sctp_ifa *sctp_ifa)
 2359 {
 2360         struct sctp_tmit_chunk *chk, *nchk;
 2361         unsigned int offset, asconf_limit;
 2362         struct sctp_asconf_chunk *acp;
 2363         struct sctp_asconf_paramhdr *aph;
 2364         uint8_t aparam_buf[SCTP_PARAM_BUFFER_SIZE];
 2365         struct sctp_paramhdr *ph;
 2366         int add_cnt, del_cnt;
 2367         uint16_t last_param_type;
 2368 
 2369         add_cnt = del_cnt = 0;
 2370         last_param_type = 0;
 2371         TAILQ_FOREACH_SAFE(chk, &stcb->asoc.asconf_send_queue, sctp_next, nchk) {
 2372                 if (chk->data == NULL) {
 2373                         SCTPDBG(SCTP_DEBUG_ASCONF1, "is_addr_pending: No mbuf data?\n");
 2374                         continue;
 2375                 }
 2376                 offset = 0;
 2377                 acp = mtod(chk->data, struct sctp_asconf_chunk *);
 2378                 offset += sizeof(struct sctp_asconf_chunk);
 2379                 asconf_limit = ntohs(acp->ch.chunk_length);
 2380                 ph = (struct sctp_paramhdr *)sctp_m_getptr(chk->data, offset, sizeof(struct sctp_paramhdr), aparam_buf);
 2381                 if (ph == NULL) {
 2382                         SCTPDBG(SCTP_DEBUG_ASCONF1, "is_addr_pending: couldn't get lookup addr!\n");
 2383                         continue;
 2384                 }
 2385                 offset += ntohs(ph->param_length);
 2386 
 2387                 aph = (struct sctp_asconf_paramhdr *)sctp_m_getptr(chk->data, offset, sizeof(struct sctp_asconf_paramhdr), aparam_buf);
 2388                 if (aph == NULL) {
 2389                         SCTPDBG(SCTP_DEBUG_ASCONF1, "is_addr_pending: Empty ASCONF will be sent?\n");
 2390                         continue;
 2391                 }
 2392                 while (aph != NULL) {
 2393                         unsigned int param_length, param_type;
 2394 
 2395                         param_type = ntohs(aph->ph.param_type);
 2396                         param_length = ntohs(aph->ph.param_length);
 2397                         if (offset + param_length > asconf_limit) {
 2398                                 /* parameter goes beyond end of chunk! */
 2399                                 break;
 2400                         }
 2401                         if (param_length > sizeof(aparam_buf)) {
 2402                                 SCTPDBG(SCTP_DEBUG_ASCONF1, "is_addr_pending: param length (%u) larger than buffer size!\n", param_length);
 2403                                 break;
 2404                         }
 2405                         if (param_length <= sizeof(struct sctp_paramhdr)) {
 2406                                 SCTPDBG(SCTP_DEBUG_ASCONF1, "is_addr_pending: param length(%u) too short\n", param_length);
 2407                                 break;
 2408                         }
 2409                         aph = (struct sctp_asconf_paramhdr *)sctp_m_getptr(chk->data, offset, param_length, aparam_buf);
 2410                         if (aph == NULL) {
 2411                                 SCTPDBG(SCTP_DEBUG_ASCONF1, "is_addr_pending: couldn't get entire param\n");
 2412                                 break;
 2413                         }
 2414                         ph = (struct sctp_paramhdr *)(aph + 1);
 2415                         if (sctp_addr_match(ph, &sctp_ifa->address.sa) != 0) {
 2416                                 switch (param_type) {
 2417                                 case SCTP_ADD_IP_ADDRESS:
 2418                                         add_cnt++;
 2419                                         break;
 2420                                 case SCTP_DEL_IP_ADDRESS:
 2421                                         del_cnt++;
 2422                                         break;
 2423                                 default:
 2424                                         break;
 2425                                 }
 2426                                 last_param_type = param_type;
 2427                         }
 2428                         offset += SCTP_SIZE32(param_length);
 2429                         if (offset >= asconf_limit) {
 2430                                 /* no more data in the mbuf chain */
 2431                                 break;
 2432                         }
 2433                         /* get pointer to next asconf param */
 2434                         aph = (struct sctp_asconf_paramhdr *)sctp_m_getptr(chk->data, offset, sizeof(struct sctp_asconf_paramhdr), aparam_buf);
 2435                 }
 2436         }
 2437 
 2438         /*
 2439          * we want to find the sequences which consist of ADD -> DEL -> ADD
 2440          * or DEL -> ADD
 2441          */
 2442         if (add_cnt > del_cnt ||
 2443             (add_cnt == del_cnt && last_param_type == SCTP_ADD_IP_ADDRESS)) {
 2444                 return (1);
 2445         }
 2446         return (0);
 2447 }
 2448 
 2449 static struct sockaddr *
 2450 sctp_find_valid_localaddr(struct sctp_tcb *stcb, int addr_locked)
 2451 {
 2452         struct sctp_vrf *vrf = NULL;
 2453         struct sctp_ifn *sctp_ifn;
 2454         struct sctp_ifa *sctp_ifa;
 2455 
 2456         if (addr_locked == SCTP_ADDR_NOT_LOCKED)
 2457                 SCTP_IPI_ADDR_RLOCK();
 2458         vrf = sctp_find_vrf(stcb->asoc.vrf_id);
 2459         if (vrf == NULL) {
 2460                 if (addr_locked == SCTP_ADDR_NOT_LOCKED)
 2461                         SCTP_IPI_ADDR_RUNLOCK();
 2462                 return (NULL);
 2463         }
 2464         LIST_FOREACH(sctp_ifn, &vrf->ifnlist, next_ifn) {
 2465                 if (stcb->asoc.scope.loopback_scope == 0 &&
 2466                     SCTP_IFN_IS_IFT_LOOP(sctp_ifn)) {
 2467                         /* Skip if loopback_scope not set */
 2468                         continue;
 2469                 }
 2470                 LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) {
 2471                         switch (sctp_ifa->address.sa.sa_family) {
 2472 #ifdef INET
 2473                         case AF_INET:
 2474                                 if (stcb->asoc.scope.ipv4_addr_legal) {
 2475                                         struct sockaddr_in *sin;
 2476 
 2477                                         sin = &sctp_ifa->address.sin;
 2478                                         if (sin->sin_addr.s_addr == 0) {
 2479                                                 /* skip unspecifed addresses */
 2480                                                 continue;
 2481                                         }
 2482                                         if (prison_check_ip4(stcb->sctp_ep->ip_inp.inp.inp_cred,
 2483                                             &sin->sin_addr) != 0) {
 2484                                                 continue;
 2485                                         }
 2486                                         if (stcb->asoc.scope.ipv4_local_scope == 0 &&
 2487                                             IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))
 2488                                                 continue;
 2489 
 2490                                         if (sctp_is_addr_restricted(stcb, sctp_ifa) &&
 2491                                             (!sctp_is_addr_pending(stcb, sctp_ifa)))
 2492                                                 continue;
 2493                                         /*
 2494                                          * found a valid local v4 address to
 2495                                          * use
 2496                                          */
 2497                                         if (addr_locked == SCTP_ADDR_NOT_LOCKED)
 2498                                                 SCTP_IPI_ADDR_RUNLOCK();
 2499                                         return (&sctp_ifa->address.sa);
 2500                                 }
 2501                                 break;
 2502 #endif
 2503 #ifdef INET6
 2504                         case AF_INET6:
 2505                                 if (stcb->asoc.scope.ipv6_addr_legal) {
 2506                                         struct sockaddr_in6 *sin6;
 2507 
 2508                                         if (sctp_ifa->localifa_flags & SCTP_ADDR_IFA_UNUSEABLE) {
 2509                                                 continue;
 2510                                         }
 2511                                         sin6 = &sctp_ifa->address.sin6;
 2512                                         if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr)) {
 2513                                                 /*
 2514                                                  * we skip unspecifed
 2515                                                  * addresses
 2516                                                  */
 2517                                                 continue;
 2518                                         }
 2519                                         if (prison_check_ip6(stcb->sctp_ep->ip_inp.inp.inp_cred,
 2520                                             &sin6->sin6_addr) != 0) {
 2521                                                 continue;
 2522                                         }
 2523                                         if (stcb->asoc.scope.local_scope == 0 &&
 2524                                             IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))
 2525                                                 continue;
 2526                                         if (stcb->asoc.scope.site_scope == 0 &&
 2527                                             IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr))
 2528                                                 continue;
 2529 
 2530                                         if (sctp_is_addr_restricted(stcb, sctp_ifa) &&
 2531                                             (!sctp_is_addr_pending(stcb, sctp_ifa)))
 2532                                                 continue;
 2533                                         /*
 2534                                          * found a valid local v6 address to
 2535                                          * use
 2536                                          */
 2537                                         if (addr_locked == SCTP_ADDR_NOT_LOCKED)
 2538                                                 SCTP_IPI_ADDR_RUNLOCK();
 2539                                         return (&sctp_ifa->address.sa);
 2540                                 }
 2541                                 break;
 2542 #endif
 2543                         default:
 2544                                 break;
 2545                         }
 2546                 }
 2547         }
 2548         /* no valid addresses found */
 2549         if (addr_locked == SCTP_ADDR_NOT_LOCKED)
 2550                 SCTP_IPI_ADDR_RUNLOCK();
 2551         return (NULL);
 2552 }
 2553 
 2554 static struct sockaddr *
 2555 sctp_find_valid_localaddr_ep(struct sctp_tcb *stcb)
 2556 {
 2557         struct sctp_laddr *laddr;
 2558 
 2559         LIST_FOREACH(laddr, &stcb->sctp_ep->sctp_addr_list, sctp_nxt_addr) {
 2560                 if (laddr->ifa == NULL) {
 2561                         continue;
 2562                 }
 2563                 /* is the address restricted ? */
 2564                 if (sctp_is_addr_restricted(stcb, laddr->ifa) &&
 2565                     (!sctp_is_addr_pending(stcb, laddr->ifa)))
 2566                         continue;
 2567 
 2568                 /* found a valid local address to use */
 2569                 return (&laddr->ifa->address.sa);
 2570         }
 2571         /* no valid addresses found */
 2572         return (NULL);
 2573 }
 2574 
 2575 /*
 2576  * builds an ASCONF chunk from queued ASCONF params.
 2577  * returns NULL on error (no mbuf, no ASCONF params queued, etc).
 2578  */
 2579 struct mbuf *
 2580 sctp_compose_asconf(struct sctp_tcb *stcb, int *retlen, int addr_locked)
 2581 {
 2582         struct mbuf *m_asconf, *m_asconf_chk;
 2583         struct sctp_asconf_addr *aa;
 2584         struct sctp_asconf_chunk *acp;
 2585         struct sctp_asconf_paramhdr *aph;
 2586         struct sctp_asconf_addr_param *aap;
 2587         uint32_t p_length;
 2588         uint32_t correlation_id = 1;    /* 0 is reserved... */
 2589         caddr_t ptr, lookup_ptr;
 2590         uint8_t lookup_used = 0;
 2591 
 2592         /* are there any asconf params to send? */
 2593         TAILQ_FOREACH(aa, &stcb->asoc.asconf_queue, next) {
 2594                 if (aa->sent == 0)
 2595                         break;
 2596         }
 2597         if (aa == NULL)
 2598                 return (NULL);
 2599 
 2600         /*
 2601          * get a chunk header mbuf and a cluster for the asconf params since
 2602          * it's simpler to fill in the asconf chunk header lookup address on
 2603          * the fly
 2604          */
 2605         m_asconf_chk = sctp_get_mbuf_for_msg(sizeof(struct sctp_asconf_chunk), 0, M_NOWAIT, 1, MT_DATA);
 2606         if (m_asconf_chk == NULL) {
 2607                 /* no mbuf's */
 2608                 SCTPDBG(SCTP_DEBUG_ASCONF1,
 2609                     "compose_asconf: couldn't get chunk mbuf!\n");
 2610                 return (NULL);
 2611         }
 2612         m_asconf = sctp_get_mbuf_for_msg(MCLBYTES, 0, M_NOWAIT, 1, MT_DATA);
 2613         if (m_asconf == NULL) {
 2614                 /* no mbuf's */
 2615                 SCTPDBG(SCTP_DEBUG_ASCONF1,
 2616                     "compose_asconf: couldn't get mbuf!\n");
 2617                 sctp_m_freem(m_asconf_chk);
 2618                 return (NULL);
 2619         }
 2620         SCTP_BUF_LEN(m_asconf_chk) = sizeof(struct sctp_asconf_chunk);
 2621         SCTP_BUF_LEN(m_asconf) = 0;
 2622         acp = mtod(m_asconf_chk, struct sctp_asconf_chunk *);
 2623         bzero(acp, sizeof(struct sctp_asconf_chunk));
 2624         /* save pointers to lookup address and asconf params */
 2625         lookup_ptr = (caddr_t)(acp + 1);        /* after the header */
 2626         ptr = mtod(m_asconf, caddr_t);  /* beginning of cluster */
 2627 
 2628         /* fill in chunk header info */
 2629         acp->ch.chunk_type = SCTP_ASCONF;
 2630         acp->ch.chunk_flags = 0;
 2631         acp->serial_number = htonl(stcb->asoc.asconf_seq_out);
 2632         stcb->asoc.asconf_seq_out++;
 2633 
 2634         /* add parameters... up to smallest MTU allowed */
 2635         TAILQ_FOREACH(aa, &stcb->asoc.asconf_queue, next) {
 2636                 if (aa->sent)
 2637                         continue;
 2638                 /* get the parameter length */
 2639                 p_length = SCTP_SIZE32(aa->ap.aph.ph.param_length);
 2640                 /* will it fit in current chunk? */
 2641                 if ((SCTP_BUF_LEN(m_asconf) + p_length > stcb->asoc.smallest_mtu) ||
 2642                     (SCTP_BUF_LEN(m_asconf) + p_length > MCLBYTES)) {
 2643                         /* won't fit, so we're done with this chunk */
 2644                         break;
 2645                 }
 2646                 /* assign (and store) a correlation id */
 2647                 aa->ap.aph.correlation_id = correlation_id++;
 2648 
 2649                 /*
 2650                  * fill in address if we're doing a delete this is a simple
 2651                  * way for us to fill in the correlation address, which
 2652                  * should only be used by the peer if we're deleting our
 2653                  * source address and adding a new address (e.g. renumbering
 2654                  * case)
 2655                  */
 2656                 if (lookup_used == 0 &&
 2657                     (aa->special_del == 0) &&
 2658                     aa->ap.aph.ph.param_type == SCTP_DEL_IP_ADDRESS) {
 2659                         struct sctp_ipv6addr_param *lookup;
 2660                         uint16_t p_size, addr_size;
 2661 
 2662                         lookup = (struct sctp_ipv6addr_param *)lookup_ptr;
 2663                         lookup->ph.param_type =
 2664                             htons(aa->ap.addrp.ph.param_type);
 2665                         if (aa->ap.addrp.ph.param_type == SCTP_IPV6_ADDRESS) {
 2666                                 /* copy IPv6 address */
 2667                                 p_size = sizeof(struct sctp_ipv6addr_param);
 2668                                 addr_size = sizeof(struct in6_addr);
 2669                         } else {
 2670                                 /* copy IPv4 address */
 2671                                 p_size = sizeof(struct sctp_ipv4addr_param);
 2672                                 addr_size = sizeof(struct in_addr);
 2673                         }
 2674                         lookup->ph.param_length = htons(SCTP_SIZE32(p_size));
 2675                         memcpy(lookup->addr, &aa->ap.addrp.addr, addr_size);
 2676                         SCTP_BUF_LEN(m_asconf_chk) += SCTP_SIZE32(p_size);
 2677                         lookup_used = 1;
 2678                 }
 2679                 /* copy into current space */
 2680                 memcpy(ptr, &aa->ap, p_length);
 2681 
 2682                 /* network elements and update lengths */
 2683                 aph = (struct sctp_asconf_paramhdr *)ptr;
 2684                 aap = (struct sctp_asconf_addr_param *)ptr;
 2685                 /* correlation_id is transparent to peer, no htonl needed */
 2686                 aph->ph.param_type = htons(aph->ph.param_type);
 2687                 aph->ph.param_length = htons(aph->ph.param_length);
 2688                 aap->addrp.ph.param_type = htons(aap->addrp.ph.param_type);
 2689                 aap->addrp.ph.param_length = htons(aap->addrp.ph.param_length);
 2690 
 2691                 SCTP_BUF_LEN(m_asconf) += SCTP_SIZE32(p_length);
 2692                 ptr += SCTP_SIZE32(p_length);
 2693 
 2694                 /*
 2695                  * these params are removed off the pending list upon
 2696                  * getting an ASCONF-ACK back from the peer, just set flag
 2697                  */
 2698                 aa->sent = 1;
 2699         }
 2700         /* check to see if the lookup addr has been populated yet */
 2701         if (lookup_used == 0) {
 2702                 /* NOTE: if the address param is optional, can skip this... */
 2703                 /* add any valid (existing) address... */
 2704                 struct sctp_ipv6addr_param *lookup;
 2705                 uint16_t p_size, addr_size;
 2706                 struct sockaddr *found_addr;
 2707                 caddr_t addr_ptr;
 2708 
 2709                 if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL)
 2710                         found_addr = sctp_find_valid_localaddr(stcb,
 2711                             addr_locked);
 2712                 else
 2713                         found_addr = sctp_find_valid_localaddr_ep(stcb);
 2714 
 2715                 lookup = (struct sctp_ipv6addr_param *)lookup_ptr;
 2716                 if (found_addr != NULL) {
 2717                         switch (found_addr->sa_family) {
 2718 #ifdef INET6
 2719                         case AF_INET6:
 2720                                 /* copy IPv6 address */
 2721                                 lookup->ph.param_type =
 2722                                     htons(SCTP_IPV6_ADDRESS);
 2723                                 p_size = sizeof(struct sctp_ipv6addr_param);
 2724                                 addr_size = sizeof(struct in6_addr);
 2725                                 addr_ptr = (caddr_t)&((struct sockaddr_in6 *)
 2726                                     found_addr)->sin6_addr;
 2727                                 break;
 2728 #endif
 2729 #ifdef INET
 2730                         case AF_INET:
 2731                                 /* copy IPv4 address */
 2732                                 lookup->ph.param_type =
 2733                                     htons(SCTP_IPV4_ADDRESS);
 2734                                 p_size = sizeof(struct sctp_ipv4addr_param);
 2735                                 addr_size = sizeof(struct in_addr);
 2736                                 addr_ptr = (caddr_t)&((struct sockaddr_in *)
 2737                                     found_addr)->sin_addr;
 2738                                 break;
 2739 #endif
 2740                         default:
 2741                                 p_size = 0;
 2742                                 addr_size = 0;
 2743                                 addr_ptr = NULL;
 2744                                 break;
 2745                         }
 2746                         lookup->ph.param_length = htons(SCTP_SIZE32(p_size));
 2747                         memcpy(lookup->addr, addr_ptr, addr_size);
 2748                         SCTP_BUF_LEN(m_asconf_chk) += SCTP_SIZE32(p_size);
 2749                 } else {
 2750                         /* uh oh... don't have any address?? */
 2751                         SCTPDBG(SCTP_DEBUG_ASCONF1,
 2752                             "compose_asconf: no lookup addr!\n");
 2753                         /* XXX for now, we send a IPv4 address of 0.0.0.0 */
 2754                         lookup->ph.param_type = htons(SCTP_IPV4_ADDRESS);
 2755                         lookup->ph.param_length = htons(SCTP_SIZE32(sizeof(struct sctp_ipv4addr_param)));
 2756                         bzero(lookup->addr, sizeof(struct in_addr));
 2757                         SCTP_BUF_LEN(m_asconf_chk) += SCTP_SIZE32(sizeof(struct sctp_ipv4addr_param));
 2758                 }
 2759         }
 2760         /* chain it all together */
 2761         SCTP_BUF_NEXT(m_asconf_chk) = m_asconf;
 2762         *retlen = SCTP_BUF_LEN(m_asconf_chk) + SCTP_BUF_LEN(m_asconf);
 2763         acp->ch.chunk_length = htons(*retlen);
 2764 
 2765         return (m_asconf_chk);
 2766 }
 2767 
 2768 /*
 2769  * section to handle address changes before an association is up eg. changes
 2770  * during INIT/INIT-ACK/COOKIE-ECHO handshake
 2771  */
 2772 
 2773 /*
 2774  * processes the (local) addresses in the INIT-ACK chunk
 2775  */
 2776 static void
 2777 sctp_process_initack_addresses(struct sctp_tcb *stcb, struct mbuf *m,
 2778     unsigned int offset, unsigned int length)
 2779 {
 2780         struct sctp_paramhdr tmp_param, *ph;
 2781         uint16_t plen, ptype;
 2782         struct sctp_ifa *sctp_ifa;
 2783         union sctp_sockstore store;
 2784 
 2785 #ifdef INET6
 2786         struct sctp_ipv6addr_param addr6_store;
 2787 
 2788 #endif
 2789 #ifdef INET
 2790         struct sctp_ipv4addr_param addr4_store;
 2791 
 2792 #endif
 2793 
 2794         SCTPDBG(SCTP_DEBUG_ASCONF2, "processing init-ack addresses\n");
 2795         if (stcb == NULL)       /* Un-needed check for SA */
 2796                 return;
 2797 
 2798         /* convert to upper bound */
 2799         length += offset;
 2800 
 2801         if ((offset + sizeof(struct sctp_paramhdr)) > length) {
 2802                 return;
 2803         }
 2804         /* go through the addresses in the init-ack */
 2805         ph = (struct sctp_paramhdr *)
 2806             sctp_m_getptr(m, offset, sizeof(struct sctp_paramhdr),
 2807             (uint8_t *) & tmp_param);
 2808         while (ph != NULL) {
 2809                 ptype = ntohs(ph->param_type);
 2810                 plen = ntohs(ph->param_length);
 2811                 switch (ptype) {
 2812 #ifdef INET6
 2813                 case SCTP_IPV6_ADDRESS:
 2814                         {
 2815                                 struct sctp_ipv6addr_param *a6p;
 2816 
 2817                                 /* get the entire IPv6 address param */
 2818                                 a6p = (struct sctp_ipv6addr_param *)
 2819                                     sctp_m_getptr(m, offset,
 2820                                     sizeof(struct sctp_ipv6addr_param),
 2821                                     (uint8_t *) & addr6_store);
 2822                                 if (plen != sizeof(struct sctp_ipv6addr_param) ||
 2823                                     a6p == NULL) {
 2824                                         return;
 2825                                 }
 2826                                 memset(&store, 0, sizeof(union sctp_sockstore));
 2827                                 store.sin6.sin6_family = AF_INET6;
 2828                                 store.sin6.sin6_len = sizeof(struct sockaddr_in6);
 2829                                 store.sin6.sin6_port = stcb->rport;
 2830                                 memcpy(&store.sin6.sin6_addr, a6p->addr, sizeof(struct in6_addr));
 2831                                 break;
 2832                         }
 2833 #endif
 2834 #ifdef INET
 2835                 case SCTP_IPV4_ADDRESS:
 2836                         {
 2837                                 struct sctp_ipv4addr_param *a4p;
 2838 
 2839                                 /* get the entire IPv4 address param */
 2840                                 a4p = (struct sctp_ipv4addr_param *)sctp_m_getptr(m, offset,
 2841                                     sizeof(struct sctp_ipv4addr_param),
 2842                                     (uint8_t *) & addr4_store);
 2843                                 if (plen != sizeof(struct sctp_ipv4addr_param) ||
 2844                                     a4p == NULL) {
 2845                                         return;
 2846                                 }
 2847                                 memset(&store, 0, sizeof(union sctp_sockstore));
 2848                                 store.sin.sin_family = AF_INET;
 2849                                 store.sin.sin_len = sizeof(struct sockaddr_in);
 2850                                 store.sin.sin_port = stcb->rport;
 2851                                 store.sin.sin_addr.s_addr = a4p->addr;
 2852                                 break;
 2853                         }
 2854 #endif
 2855                 default:
 2856                         goto next_addr;
 2857                 }
 2858 
 2859                 /* see if this address really (still) exists */
 2860                 sctp_ifa = sctp_find_ifa_by_addr(&store.sa, stcb->asoc.vrf_id,
 2861                     SCTP_ADDR_NOT_LOCKED);
 2862                 if (sctp_ifa == NULL) {
 2863                         /* address doesn't exist anymore */
 2864                         int status;
 2865 
 2866                         /* are ASCONFs allowed ? */
 2867                         if ((sctp_is_feature_on(stcb->sctp_ep,
 2868                             SCTP_PCB_FLAGS_DO_ASCONF)) &&
 2869                             stcb->asoc.asconf_supported) {
 2870                                 /* queue an ASCONF DEL_IP_ADDRESS */
 2871                                 status = sctp_asconf_queue_sa_delete(stcb, &store.sa);
 2872                                 /*
 2873                                  * if queued ok, and in correct state, send
 2874                                  * out the ASCONF.
 2875                                  */
 2876                                 if (status == 0 &&
 2877                                     SCTP_GET_STATE(&stcb->asoc) ==
 2878                                     SCTP_STATE_OPEN) {
 2879 #ifdef SCTP_TIMER_BASED_ASCONF
 2880                                         sctp_timer_start(SCTP_TIMER_TYPE_ASCONF,
 2881                                             stcb->sctp_ep, stcb,
 2882                                             stcb->asoc.primary_destination);
 2883 #else
 2884                                         sctp_send_asconf(stcb, NULL, SCTP_ADDR_NOT_LOCKED);
 2885 #endif
 2886                                 }
 2887                         }
 2888                 }
 2889 next_addr:
 2890                 /*
 2891                  * Sanity check:  Make sure the length isn't 0, otherwise
 2892                  * we'll be stuck in this loop for a long time...
 2893                  */
 2894                 if (SCTP_SIZE32(plen) == 0) {
 2895                         SCTP_PRINTF("process_initack_addrs: bad len (%d) type=%xh\n",
 2896                             plen, ptype);
 2897                         return;
 2898                 }
 2899                 /* get next parameter */
 2900                 offset += SCTP_SIZE32(plen);
 2901                 if ((offset + sizeof(struct sctp_paramhdr)) > length)
 2902                         return;
 2903                 ph = (struct sctp_paramhdr *)sctp_m_getptr(m, offset,
 2904                     sizeof(struct sctp_paramhdr), (uint8_t *) & tmp_param);
 2905         }                       /* while */
 2906 }
 2907 
 2908 /* FIX ME: need to verify return result for v6 address type if v6 disabled */
 2909 /*
 2910  * checks to see if a specific address is in the initack address list returns
 2911  * 1 if found, 0 if not
 2912  */
 2913 static uint32_t
 2914 sctp_addr_in_initack(struct mbuf *m, uint32_t offset, uint32_t length, struct sockaddr *sa)
 2915 {
 2916         struct sctp_paramhdr tmp_param, *ph;
 2917         uint16_t plen, ptype;
 2918 
 2919 #ifdef INET
 2920         struct sockaddr_in *sin;
 2921         struct sctp_ipv4addr_param *a4p;
 2922         struct sctp_ipv6addr_param addr4_store;
 2923 
 2924 #endif
 2925 #ifdef INET6
 2926         struct sockaddr_in6 *sin6;
 2927         struct sctp_ipv6addr_param *a6p;
 2928         struct sctp_ipv6addr_param addr6_store;
 2929         struct sockaddr_in6 sin6_tmp;
 2930 
 2931 #endif
 2932 
 2933         switch (sa->sa_family) {
 2934 #ifdef INET
 2935         case AF_INET:
 2936                 break;
 2937 #endif
 2938 #ifdef INET6
 2939         case AF_INET6:
 2940                 break;
 2941 #endif
 2942         default:
 2943                 return (0);
 2944         }
 2945 
 2946         SCTPDBG(SCTP_DEBUG_ASCONF2, "find_initack_addr: starting search for ");
 2947         SCTPDBG_ADDR(SCTP_DEBUG_ASCONF2, sa);
 2948         /* convert to upper bound */
 2949         length += offset;
 2950 
 2951         if ((offset + sizeof(struct sctp_paramhdr)) > length) {
 2952                 SCTPDBG(SCTP_DEBUG_ASCONF1,
 2953                     "find_initack_addr: invalid offset?\n");
 2954                 return (0);
 2955         }
 2956         /* go through the addresses in the init-ack */
 2957         ph = (struct sctp_paramhdr *)sctp_m_getptr(m, offset,
 2958             sizeof(struct sctp_paramhdr), (uint8_t *) & tmp_param);
 2959         while (ph != NULL) {
 2960                 ptype = ntohs(ph->param_type);
 2961                 plen = ntohs(ph->param_length);
 2962                 switch (ptype) {
 2963 #ifdef INET6
 2964                 case SCTP_IPV6_ADDRESS:
 2965                         if (sa->sa_family == AF_INET6) {
 2966                                 /* get the entire IPv6 address param */
 2967                                 if (plen != sizeof(struct sctp_ipv6addr_param)) {
 2968                                         break;
 2969                                 }
 2970                                 /* get the entire IPv6 address param */
 2971                                 a6p = (struct sctp_ipv6addr_param *)
 2972                                     sctp_m_getptr(m, offset,
 2973                                     sizeof(struct sctp_ipv6addr_param),
 2974                                     (uint8_t *) & addr6_store);
 2975                                 if (a6p == NULL) {
 2976                                         return (0);
 2977                                 }
 2978                                 sin6 = (struct sockaddr_in6 *)sa;
 2979                                 if (IN6_IS_SCOPE_LINKLOCAL(&sin6->sin6_addr)) {
 2980                                         /* create a copy and clear scope */
 2981                                         memcpy(&sin6_tmp, sin6,
 2982                                             sizeof(struct sockaddr_in6));
 2983                                         sin6 = &sin6_tmp;
 2984                                         in6_clearscope(&sin6->sin6_addr);
 2985                                 }
 2986                                 if (memcmp(&sin6->sin6_addr, a6p->addr,
 2987                                     sizeof(struct in6_addr)) == 0) {
 2988                                         /* found it */
 2989                                         return (1);
 2990                                 }
 2991                         }
 2992                         break;
 2993 #endif                          /* INET6 */
 2994 #ifdef INET
 2995                 case SCTP_IPV4_ADDRESS:
 2996                         if (sa->sa_family == AF_INET) {
 2997                                 if (plen != sizeof(struct sctp_ipv4addr_param)) {
 2998                                         break;
 2999                                 }
 3000                                 /* get the entire IPv4 address param */
 3001                                 a4p = (struct sctp_ipv4addr_param *)
 3002                                     sctp_m_getptr(m, offset,
 3003                                     sizeof(struct sctp_ipv4addr_param),
 3004                                     (uint8_t *) & addr4_store);
 3005                                 if (a4p == NULL) {
 3006                                         return (0);
 3007                                 }
 3008                                 sin = (struct sockaddr_in *)sa;
 3009                                 if (sin->sin_addr.s_addr == a4p->addr) {
 3010                                         /* found it */
 3011                                         return (1);
 3012                                 }
 3013                         }
 3014                         break;
 3015 #endif
 3016                 default:
 3017                         break;
 3018                 }
 3019                 /* get next parameter */
 3020                 offset += SCTP_SIZE32(plen);
 3021                 if (offset + sizeof(struct sctp_paramhdr) > length) {
 3022                         return (0);
 3023                 }
 3024                 ph = (struct sctp_paramhdr *)
 3025                     sctp_m_getptr(m, offset, sizeof(struct sctp_paramhdr),
 3026                     (uint8_t *) & tmp_param);
 3027         }                       /* while */
 3028         /* not found! */
 3029         return (0);
 3030 }
 3031 
 3032 /*
 3033  * makes sure that the current endpoint local addr list is consistent with
 3034  * the new association (eg. subset bound, asconf allowed) adds addresses as
 3035  * necessary
 3036  */
 3037 static void
 3038 sctp_check_address_list_ep(struct sctp_tcb *stcb, struct mbuf *m, int offset,
 3039     int length, struct sockaddr *init_addr)
 3040 {
 3041         struct sctp_laddr *laddr;
 3042 
 3043         /* go through the endpoint list */
 3044         LIST_FOREACH(laddr, &stcb->sctp_ep->sctp_addr_list, sctp_nxt_addr) {
 3045                 /* be paranoid and validate the laddr */
 3046                 if (laddr->ifa == NULL) {
 3047                         SCTPDBG(SCTP_DEBUG_ASCONF1,
 3048                             "check_addr_list_ep: laddr->ifa is NULL");
 3049                         continue;
 3050                 }
 3051                 if (laddr->ifa == NULL) {
 3052                         SCTPDBG(SCTP_DEBUG_ASCONF1, "check_addr_list_ep: laddr->ifa->ifa_addr is NULL");
 3053                         continue;
 3054                 }
 3055                 /* do i have it implicitly? */
 3056                 if (sctp_cmpaddr(&laddr->ifa->address.sa, init_addr)) {
 3057                         continue;
 3058                 }
 3059                 /* check to see if in the init-ack */
 3060                 if (!sctp_addr_in_initack(m, offset, length, &laddr->ifa->address.sa)) {
 3061                         /* try to add it */
 3062                         sctp_addr_mgmt_assoc(stcb->sctp_ep, stcb, laddr->ifa,
 3063                             SCTP_ADD_IP_ADDRESS, SCTP_ADDR_NOT_LOCKED);
 3064                 }
 3065         }
 3066 }
 3067 
 3068 /*
 3069  * makes sure that the current kernel address list is consistent with the new
 3070  * association (with all addrs bound) adds addresses as necessary
 3071  */
 3072 static void
 3073 sctp_check_address_list_all(struct sctp_tcb *stcb, struct mbuf *m, int offset,
 3074     int length, struct sockaddr *init_addr,
 3075     uint16_t local_scope, uint16_t site_scope,
 3076     uint16_t ipv4_scope, uint16_t loopback_scope)
 3077 {
 3078         struct sctp_vrf *vrf = NULL;
 3079         struct sctp_ifn *sctp_ifn;
 3080         struct sctp_ifa *sctp_ifa;
 3081         uint32_t vrf_id;
 3082 
 3083 #ifdef INET
 3084         struct sockaddr_in *sin;
 3085 
 3086 #endif
 3087 #ifdef INET6
 3088         struct sockaddr_in6 *sin6;
 3089 
 3090 #endif
 3091 
 3092         if (stcb) {
 3093                 vrf_id = stcb->asoc.vrf_id;
 3094         } else {
 3095                 return;
 3096         }
 3097         SCTP_IPI_ADDR_RLOCK();
 3098         vrf = sctp_find_vrf(vrf_id);
 3099         if (vrf == NULL) {
 3100                 SCTP_IPI_ADDR_RUNLOCK();
 3101                 return;
 3102         }
 3103         /* go through all our known interfaces */
 3104         LIST_FOREACH(sctp_ifn, &vrf->ifnlist, next_ifn) {
 3105                 if (loopback_scope == 0 && SCTP_IFN_IS_IFT_LOOP(sctp_ifn)) {
 3106                         /* skip loopback interface */
 3107                         continue;
 3108                 }
 3109                 /* go through each interface address */
 3110                 LIST_FOREACH(sctp_ifa, &sctp_ifn->ifalist, next_ifa) {
 3111                         /* do i have it implicitly? */
 3112                         if (sctp_cmpaddr(&sctp_ifa->address.sa, init_addr)) {
 3113                                 continue;
 3114                         }
 3115                         switch (sctp_ifa->address.sa.sa_family) {
 3116 #ifdef INET
 3117                         case AF_INET:
 3118                                 sin = &sctp_ifa->address.sin;
 3119                                 if (prison_check_ip4(stcb->sctp_ep->ip_inp.inp.inp_cred,
 3120                                     &sin->sin_addr) != 0) {
 3121                                         continue;
 3122                                 }
 3123                                 if ((ipv4_scope == 0) &&
 3124                                     (IN4_ISPRIVATE_ADDRESS(&sin->sin_addr))) {
 3125                                         /* private address not in scope */
 3126                                         continue;
 3127                                 }
 3128                                 break;
 3129 #endif
 3130 #ifdef INET6
 3131                         case AF_INET6:
 3132                                 sin6 = &sctp_ifa->address.sin6;
 3133                                 if (prison_check_ip6(stcb->sctp_ep->ip_inp.inp.inp_cred,
 3134                                     &sin6->sin6_addr) != 0) {
 3135                                         continue;
 3136                                 }
 3137                                 if ((local_scope == 0) &&
 3138                                     (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))) {
 3139                                         continue;
 3140                                 }
 3141                                 if ((site_scope == 0) &&
 3142                                     (IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr))) {
 3143                                         continue;
 3144                                 }
 3145                                 break;
 3146 #endif
 3147                         default:
 3148                                 break;
 3149                         }
 3150                         /* check to see if in the init-ack */
 3151                         if (!sctp_addr_in_initack(m, offset, length, &sctp_ifa->address.sa)) {
 3152                                 /* try to add it */
 3153                                 sctp_addr_mgmt_assoc(stcb->sctp_ep, stcb,
 3154                                     sctp_ifa, SCTP_ADD_IP_ADDRESS,
 3155                                     SCTP_ADDR_LOCKED);
 3156                         }
 3157                 }               /* end foreach ifa */
 3158         }                       /* end foreach ifn */
 3159         SCTP_IPI_ADDR_RUNLOCK();
 3160 }
 3161 
 3162 /*
 3163  * validates an init-ack chunk (from a cookie-echo) with current addresses
 3164  * adds addresses from the init-ack into our local address list, if needed
 3165  * queues asconf adds/deletes addresses as needed and makes appropriate list
 3166  * changes for source address selection m, offset: points to the start of the
 3167  * address list in an init-ack chunk length: total length of the address
 3168  * params only init_addr: address where my INIT-ACK was sent from
 3169  */
 3170 void
 3171 sctp_check_address_list(struct sctp_tcb *stcb, struct mbuf *m, int offset,
 3172     int length, struct sockaddr *init_addr,
 3173     uint16_t local_scope, uint16_t site_scope,
 3174     uint16_t ipv4_scope, uint16_t loopback_scope)
 3175 {
 3176         /* process the local addresses in the initack */
 3177         sctp_process_initack_addresses(stcb, m, offset, length);
 3178 
 3179         if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
 3180                 /* bound all case */
 3181                 sctp_check_address_list_all(stcb, m, offset, length, init_addr,
 3182                     local_scope, site_scope, ipv4_scope, loopback_scope);
 3183         } else {
 3184                 /* subset bound case */
 3185                 if (sctp_is_feature_on(stcb->sctp_ep,
 3186                     SCTP_PCB_FLAGS_DO_ASCONF)) {
 3187                         /* asconf's allowed */
 3188                         sctp_check_address_list_ep(stcb, m, offset, length,
 3189                             init_addr);
 3190                 }
 3191                 /* else, no asconfs allowed, so what we sent is what we get */
 3192         }
 3193 }
 3194 
 3195 /*
 3196  * sctp_bindx() support
 3197  */
 3198 uint32_t
 3199 sctp_addr_mgmt_ep_sa(struct sctp_inpcb *inp, struct sockaddr *sa,
 3200     uint32_t type, uint32_t vrf_id, struct sctp_ifa *sctp_ifap)
 3201 {
 3202         struct sctp_ifa *ifa;
 3203         struct sctp_laddr *laddr, *nladdr;
 3204 
 3205         if (sa->sa_len == 0) {
 3206                 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_ASCONF, EINVAL);
 3207                 return (EINVAL);
 3208         }
 3209         if (sctp_ifap) {
 3210                 ifa = sctp_ifap;
 3211         } else if (type == SCTP_ADD_IP_ADDRESS) {
 3212                 /* For an add the address MUST be on the system */
 3213                 ifa = sctp_find_ifa_by_addr(sa, vrf_id, SCTP_ADDR_NOT_LOCKED);
 3214         } else if (type == SCTP_DEL_IP_ADDRESS) {
 3215                 /* For a delete we need to find it in the inp */
 3216                 ifa = sctp_find_ifa_in_ep(inp, sa, SCTP_ADDR_NOT_LOCKED);
 3217         } else {
 3218                 ifa = NULL;
 3219         }
 3220         if (ifa != NULL) {
 3221                 if (type == SCTP_ADD_IP_ADDRESS) {
 3222                         sctp_add_local_addr_ep(inp, ifa, type);
 3223                 } else if (type == SCTP_DEL_IP_ADDRESS) {
 3224                         if (inp->laddr_count < 2) {
 3225                                 /* can't delete the last local address */
 3226                                 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_ASCONF, EINVAL);
 3227                                 return (EINVAL);
 3228                         }
 3229                         LIST_FOREACH(laddr, &inp->sctp_addr_list,
 3230                             sctp_nxt_addr) {
 3231                                 if (ifa == laddr->ifa) {
 3232                                         /* Mark in the delete */
 3233                                         laddr->action = type;
 3234                                 }
 3235                         }
 3236                 }
 3237                 if (LIST_EMPTY(&inp->sctp_asoc_list)) {
 3238                         /*
 3239                          * There is no need to start the iterator if the inp
 3240                          * has no associations.
 3241                          */
 3242                         if (type == SCTP_DEL_IP_ADDRESS) {
 3243                                 LIST_FOREACH_SAFE(laddr, &inp->sctp_addr_list, sctp_nxt_addr, nladdr) {
 3244                                         if (laddr->ifa == ifa) {
 3245                                                 sctp_del_local_addr_ep(inp, ifa);
 3246                                         }
 3247                                 }
 3248                         }
 3249                 } else {
 3250                         struct sctp_asconf_iterator *asc;
 3251                         struct sctp_laddr *wi;
 3252                         int ret;
 3253 
 3254                         SCTP_MALLOC(asc, struct sctp_asconf_iterator *,
 3255                             sizeof(struct sctp_asconf_iterator),
 3256                             SCTP_M_ASC_IT);
 3257                         if (asc == NULL) {
 3258                                 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_ASCONF, ENOMEM);
 3259                                 return (ENOMEM);
 3260                         }
 3261                         wi = SCTP_ZONE_GET(SCTP_BASE_INFO(ipi_zone_laddr), struct sctp_laddr);
 3262                         if (wi == NULL) {
 3263                                 SCTP_FREE(asc, SCTP_M_ASC_IT);
 3264                                 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_ASCONF, ENOMEM);
 3265                                 return (ENOMEM);
 3266                         }
 3267                         LIST_INIT(&asc->list_of_work);
 3268                         asc->cnt = 1;
 3269                         SCTP_INCR_LADDR_COUNT();
 3270                         wi->ifa = ifa;
 3271                         wi->action = type;
 3272                         atomic_add_int(&ifa->refcount, 1);
 3273                         LIST_INSERT_HEAD(&asc->list_of_work, wi, sctp_nxt_addr);
 3274                         ret = sctp_initiate_iterator(sctp_asconf_iterator_ep,
 3275                             sctp_asconf_iterator_stcb,
 3276                             sctp_asconf_iterator_ep_end,
 3277                             SCTP_PCB_ANY_FLAGS,
 3278                             SCTP_PCB_ANY_FEATURES,
 3279                             SCTP_ASOC_ANY_STATE,
 3280                             (void *)asc, 0,
 3281                             sctp_asconf_iterator_end, inp, 0);
 3282                         if (ret) {
 3283                                 SCTP_PRINTF("Failed to initiate iterator for addr_mgmt_ep_sa\n");
 3284                                 SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_ASCONF, EFAULT);
 3285                                 sctp_asconf_iterator_end(asc, 0);
 3286                                 return (EFAULT);
 3287                         }
 3288                 }
 3289                 return (0);
 3290         } else {
 3291                 /* invalid address! */
 3292                 SCTP_LTRACE_ERR_RET(NULL, NULL, NULL, SCTP_FROM_SCTP_ASCONF, EADDRNOTAVAIL);
 3293                 return (EADDRNOTAVAIL);
 3294         }
 3295 }
 3296 
 3297 void
 3298 sctp_asconf_send_nat_state_update(struct sctp_tcb *stcb,
 3299     struct sctp_nets *net)
 3300 {
 3301         struct sctp_asconf_addr *aa;
 3302         struct sctp_ifa *sctp_ifap;
 3303         struct sctp_asconf_tag_param *vtag;
 3304 
 3305 #ifdef INET
 3306         struct sockaddr_in *to;
 3307 
 3308 #endif
 3309 #ifdef INET6
 3310         struct sockaddr_in6 *to6;
 3311 
 3312 #endif
 3313         if (net == NULL) {
 3314                 SCTPDBG(SCTP_DEBUG_ASCONF1, "sctp_asconf_send_nat_state_update: Missing net\n");
 3315                 return;
 3316         }
 3317         if (stcb == NULL) {
 3318                 SCTPDBG(SCTP_DEBUG_ASCONF1, "sctp_asconf_send_nat_state_update: Missing stcb\n");
 3319                 return;
 3320         }
 3321         /*
 3322          * Need to have in the asconf: - vtagparam(my_vtag/peer_vtag) -
 3323          * add(0.0.0.0) - del(0.0.0.0) - Any global addresses add(addr)
 3324          */
 3325         SCTP_MALLOC(aa, struct sctp_asconf_addr *, sizeof(*aa),
 3326             SCTP_M_ASC_ADDR);
 3327         if (aa == NULL) {
 3328                 /* didn't get memory */
 3329                 SCTPDBG(SCTP_DEBUG_ASCONF1,
 3330                     "sctp_asconf_send_nat_state_update: failed to get memory!\n");
 3331                 return;
 3332         }
 3333         aa->special_del = 0;
 3334         /* fill in asconf address parameter fields */
 3335         /* top level elements are "networked" during send */
 3336         aa->ifa = NULL;
 3337         aa->sent = 0;           /* clear sent flag */
 3338         vtag = (struct sctp_asconf_tag_param *)&aa->ap.aph;
 3339         vtag->aph.ph.param_type = SCTP_NAT_VTAGS;
 3340         vtag->aph.ph.param_length = sizeof(struct sctp_asconf_tag_param);
 3341         vtag->local_vtag = htonl(stcb->asoc.my_vtag);
 3342         vtag->remote_vtag = htonl(stcb->asoc.peer_vtag);
 3343         TAILQ_INSERT_TAIL(&stcb->asoc.asconf_queue, aa, next);
 3344 
 3345         SCTP_MALLOC(aa, struct sctp_asconf_addr *, sizeof(*aa),
 3346             SCTP_M_ASC_ADDR);
 3347         if (aa == NULL) {
 3348                 /* didn't get memory */
 3349                 SCTPDBG(SCTP_DEBUG_ASCONF1,
 3350                     "sctp_asconf_send_nat_state_update: failed to get memory!\n");
 3351                 return;
 3352         }
 3353         memset(aa, 0, sizeof(struct sctp_asconf_addr));
 3354         /* fill in asconf address parameter fields */
 3355         /* ADD(0.0.0.0) */
 3356         switch (net->ro._l_addr.sa.sa_family) {
 3357 #ifdef INET
 3358         case AF_INET:
 3359                 aa->ap.aph.ph.param_type = SCTP_ADD_IP_ADDRESS;
 3360                 aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_addrv4_param);
 3361                 aa->ap.addrp.ph.param_type = SCTP_IPV4_ADDRESS;
 3362                 aa->ap.addrp.ph.param_length = sizeof(struct sctp_ipv4addr_param);
 3363                 /* No need to add an address, we are using 0.0.0.0 */
 3364                 TAILQ_INSERT_TAIL(&stcb->asoc.asconf_queue, aa, next);
 3365                 break;
 3366 #endif
 3367 #ifdef INET6
 3368         case AF_INET6:
 3369                 aa->ap.aph.ph.param_type = SCTP_ADD_IP_ADDRESS;
 3370                 aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_addr_param);
 3371                 aa->ap.addrp.ph.param_type = SCTP_IPV6_ADDRESS;
 3372                 aa->ap.addrp.ph.param_length = sizeof(struct sctp_ipv6addr_param);
 3373                 /* No need to add an address, we are using 0.0.0.0 */
 3374                 TAILQ_INSERT_TAIL(&stcb->asoc.asconf_queue, aa, next);
 3375                 break;
 3376 #endif
 3377         default:
 3378                 SCTPDBG(SCTP_DEBUG_ASCONF1,
 3379                     "sctp_asconf_send_nat_state_update: unknown address family\n");
 3380                 SCTP_FREE(aa, SCTP_M_ASC_ADDR);
 3381                 return;
 3382         }
 3383         SCTP_MALLOC(aa, struct sctp_asconf_addr *, sizeof(*aa),
 3384             SCTP_M_ASC_ADDR);
 3385         if (aa == NULL) {
 3386                 /* didn't get memory */
 3387                 SCTPDBG(SCTP_DEBUG_ASCONF1,
 3388                     "sctp_asconf_send_nat_state_update: failed to get memory!\n");
 3389                 return;
 3390         }
 3391         memset(aa, 0, sizeof(struct sctp_asconf_addr));
 3392         /* fill in asconf address parameter fields */
 3393         /* ADD(0.0.0.0) */
 3394         switch (net->ro._l_addr.sa.sa_family) {
 3395 #ifdef INET
 3396         case AF_INET:
 3397                 aa->ap.aph.ph.param_type = SCTP_ADD_IP_ADDRESS;
 3398                 aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_addrv4_param);
 3399                 aa->ap.addrp.ph.param_type = SCTP_IPV4_ADDRESS;
 3400                 aa->ap.addrp.ph.param_length = sizeof(struct sctp_ipv4addr_param);
 3401                 /* No need to add an address, we are using 0.0.0.0 */
 3402                 TAILQ_INSERT_TAIL(&stcb->asoc.asconf_queue, aa, next);
 3403                 break;
 3404 #endif
 3405 #ifdef INET6
 3406         case AF_INET6:
 3407                 aa->ap.aph.ph.param_type = SCTP_DEL_IP_ADDRESS;
 3408                 aa->ap.aph.ph.param_length = sizeof(struct sctp_asconf_addr_param);
 3409                 aa->ap.addrp.ph.param_type = SCTP_IPV6_ADDRESS;
 3410                 aa->ap.addrp.ph.param_length = sizeof(struct sctp_ipv6addr_param);
 3411                 /* No need to add an address, we are using 0.0.0.0 */
 3412                 TAILQ_INSERT_TAIL(&stcb->asoc.asconf_queue, aa, next);
 3413                 break;
 3414 #endif
 3415         default:
 3416                 SCTPDBG(SCTP_DEBUG_ASCONF1,
 3417                     "sctp_asconf_send_nat_state_update: unknown address family\n");
 3418                 SCTP_FREE(aa, SCTP_M_ASC_ADDR);
 3419                 return;
 3420         }
 3421         /* Now we must hunt the addresses and add all global addresses */
 3422         if (stcb->sctp_ep->sctp_flags & SCTP_PCB_FLAGS_BOUNDALL) {
 3423                 struct sctp_vrf *vrf = NULL;
 3424                 struct sctp_ifn *sctp_ifnp;
 3425                 uint32_t vrf_id;
 3426 
 3427                 vrf_id = stcb->sctp_ep->def_vrf_id;
 3428                 vrf = sctp_find_vrf(vrf_id);
 3429                 if (vrf == NULL) {
 3430                         goto skip_rest;
 3431                 }
 3432                 SCTP_IPI_ADDR_RLOCK();
 3433                 LIST_FOREACH(sctp_ifnp, &vrf->ifnlist, next_ifn) {
 3434                         LIST_FOREACH(sctp_ifap, &sctp_ifnp->ifalist, next_ifa) {
 3435                                 switch (sctp_ifap->address.sa.sa_family) {
 3436 #ifdef INET
 3437                                 case AF_INET:
 3438                                         to = &sctp_ifap->address.sin;
 3439                                         if (prison_check_ip4(stcb->sctp_ep->ip_inp.inp.inp_cred,
 3440                                             &to->sin_addr) != 0) {
 3441                                                 continue;
 3442                                         }
 3443                                         if (IN4_ISPRIVATE_ADDRESS(&to->sin_addr)) {
 3444                                                 continue;
 3445                                         }
 3446                                         if (IN4_ISLOOPBACK_ADDRESS(&to->sin_addr)) {
 3447                                                 continue;
 3448                                         }
 3449                                         break;
 3450 #endif
 3451 #ifdef INET6
 3452                                 case AF_INET6:
 3453                                         to6 = &sctp_ifap->address.sin6;
 3454                                         if (prison_check_ip6(stcb->sctp_ep->ip_inp.inp.inp_cred,
 3455                                             &to6->sin6_addr) != 0) {
 3456                                                 continue;
 3457                                         }
 3458                                         if (IN6_IS_ADDR_LOOPBACK(&to6->sin6_addr)) {
 3459                                                 continue;
 3460                                         }
 3461                                         if (IN6_IS_ADDR_LINKLOCAL(&to6->sin6_addr)) {
 3462                                                 continue;
 3463                                         }
 3464                                         break;
 3465 #endif
 3466                                 default:
 3467                                         continue;
 3468                                 }
 3469                                 sctp_asconf_queue_mgmt(stcb, sctp_ifap, SCTP_ADD_IP_ADDRESS);
 3470                         }
 3471                 }
 3472                 SCTP_IPI_ADDR_RUNLOCK();
 3473         } else {
 3474                 struct sctp_laddr *laddr;
 3475 
 3476                 LIST_FOREACH(laddr, &stcb->sctp_ep->sctp_addr_list, sctp_nxt_addr) {
 3477                         if (laddr->ifa == NULL) {
 3478                                 continue;
 3479                         }
 3480                         if (laddr->ifa->localifa_flags & SCTP_BEING_DELETED)
 3481                                 /*
 3482                                  * Address being deleted by the system, dont
 3483                                  * list.
 3484                                  */
 3485                                 continue;
 3486                         if (laddr->action == SCTP_DEL_IP_ADDRESS) {
 3487                                 /*
 3488                                  * Address being deleted on this ep don't
 3489                                  * list.
 3490                                  */
 3491                                 continue;
 3492                         }
 3493                         sctp_ifap = laddr->ifa;
 3494                         switch (sctp_ifap->address.sa.sa_family) {
 3495 #ifdef INET
 3496                         case AF_INET:
 3497                                 to = &sctp_ifap->address.sin;
 3498                                 if (IN4_ISPRIVATE_ADDRESS(&to->sin_addr)) {
 3499                                         continue;
 3500                                 }
 3501                                 if (IN4_ISLOOPBACK_ADDRESS(&to->sin_addr)) {
 3502                                         continue;
 3503                                 }
 3504                                 break;
 3505 #endif
 3506 #ifdef INET6
 3507                         case AF_INET6:
 3508                                 to6 = &sctp_ifap->address.sin6;
 3509                                 if (IN6_IS_ADDR_LOOPBACK(&to6->sin6_addr)) {
 3510                                         continue;
 3511                                 }
 3512                                 if (IN6_IS_ADDR_LINKLOCAL(&to6->sin6_addr)) {
 3513                                         continue;
 3514                                 }
 3515                                 break;
 3516 #endif
 3517                         default:
 3518                                 continue;
 3519                         }
 3520                         sctp_asconf_queue_mgmt(stcb, sctp_ifap, SCTP_ADD_IP_ADDRESS);
 3521                 }
 3522         }
 3523 skip_rest:
 3524         /* Now we must send the asconf into the queue */
 3525         sctp_send_asconf(stcb, net, SCTP_ADDR_NOT_LOCKED);
 3526 }

Cache object: 04b6fcf2557c92af07cbbd2ef3eb21cc


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.