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

Cache object: bf9ac9ff69e656c2372aa136638fd4f5


[ 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.