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


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

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

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

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

Cache object: 31b367a4c8331dca660787c024fd7218


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